1 1.1 joerg //===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg // 9 1.1 joerg // This provides Objective-C code generation targeting the GNU runtime. The 10 1.1 joerg // class in this file generates structures used by the GNU Objective-C runtime 11 1.1 joerg // library. These structures are defined in objc/objc.h and objc/objc-api.h in 12 1.1 joerg // the GNU runtime distribution. 13 1.1 joerg // 14 1.1 joerg //===----------------------------------------------------------------------===// 15 1.1 joerg 16 1.1.1.2 joerg #include "CGCXXABI.h" 17 1.1 joerg #include "CGCleanup.h" 18 1.1.1.2 joerg #include "CGObjCRuntime.h" 19 1.1 joerg #include "CodeGenFunction.h" 20 1.1 joerg #include "CodeGenModule.h" 21 1.1 joerg #include "clang/AST/ASTContext.h" 22 1.1.1.2 joerg #include "clang/AST/Attr.h" 23 1.1 joerg #include "clang/AST/Decl.h" 24 1.1 joerg #include "clang/AST/DeclObjC.h" 25 1.1 joerg #include "clang/AST/RecordLayout.h" 26 1.1 joerg #include "clang/AST/StmtObjC.h" 27 1.1 joerg #include "clang/Basic/FileManager.h" 28 1.1 joerg #include "clang/Basic/SourceManager.h" 29 1.1.1.2 joerg #include "clang/CodeGen/ConstantInitBuilder.h" 30 1.1 joerg #include "llvm/ADT/SmallVector.h" 31 1.1 joerg #include "llvm/ADT/StringMap.h" 32 1.1 joerg #include "llvm/IR/DataLayout.h" 33 1.1 joerg #include "llvm/IR/Intrinsics.h" 34 1.1 joerg #include "llvm/IR/LLVMContext.h" 35 1.1 joerg #include "llvm/IR/Module.h" 36 1.1 joerg #include "llvm/Support/Compiler.h" 37 1.1 joerg #include "llvm/Support/ConvertUTF.h" 38 1.1 joerg #include <cctype> 39 1.1 joerg 40 1.1 joerg using namespace clang; 41 1.1 joerg using namespace CodeGen; 42 1.1 joerg 43 1.1 joerg namespace { 44 1.1 joerg 45 1.1 joerg /// Class that lazily initialises the runtime function. Avoids inserting the 46 1.1 joerg /// types and the function declaration into a module if they're not used, and 47 1.1 joerg /// avoids constructing the type more than once if it's used more than once. 48 1.1 joerg class LazyRuntimeFunction { 49 1.1 joerg CodeGenModule *CGM; 50 1.1 joerg llvm::FunctionType *FTy; 51 1.1 joerg const char *FunctionName; 52 1.1 joerg llvm::FunctionCallee Function; 53 1.1 joerg 54 1.1 joerg public: 55 1.1 joerg /// Constructor leaves this class uninitialized, because it is intended to 56 1.1 joerg /// be used as a field in another class and not all of the types that are 57 1.1 joerg /// used as arguments will necessarily be available at construction time. 58 1.1 joerg LazyRuntimeFunction() 59 1.1 joerg : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {} 60 1.1 joerg 61 1.1 joerg /// Initialises the lazy function with the name, return type, and the types 62 1.1 joerg /// of the arguments. 63 1.1 joerg template <typename... Tys> 64 1.1 joerg void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy, 65 1.1 joerg Tys *... Types) { 66 1.1 joerg CGM = Mod; 67 1.1 joerg FunctionName = name; 68 1.1 joerg Function = nullptr; 69 1.1 joerg if(sizeof...(Tys)) { 70 1.1 joerg SmallVector<llvm::Type *, 8> ArgTys({Types...}); 71 1.1 joerg FTy = llvm::FunctionType::get(RetTy, ArgTys, false); 72 1.1 joerg } 73 1.1 joerg else { 74 1.1 joerg FTy = llvm::FunctionType::get(RetTy, None, false); 75 1.1 joerg } 76 1.1 joerg } 77 1.1 joerg 78 1.1 joerg llvm::FunctionType *getType() { return FTy; } 79 1.1 joerg 80 1.1 joerg /// Overloaded cast operator, allows the class to be implicitly cast to an 81 1.1 joerg /// LLVM constant. 82 1.1 joerg operator llvm::FunctionCallee() { 83 1.1 joerg if (!Function) { 84 1.1 joerg if (!FunctionName) 85 1.1 joerg return nullptr; 86 1.1 joerg Function = CGM->CreateRuntimeFunction(FTy, FunctionName); 87 1.1 joerg } 88 1.1 joerg return Function; 89 1.1 joerg } 90 1.1 joerg }; 91 1.1 joerg 92 1.1 joerg 93 1.1 joerg /// GNU Objective-C runtime code generation. This class implements the parts of 94 1.1 joerg /// Objective-C support that are specific to the GNU family of runtimes (GCC, 95 1.1 joerg /// GNUstep and ObjFW). 96 1.1 joerg class CGObjCGNU : public CGObjCRuntime { 97 1.1 joerg protected: 98 1.1 joerg /// The LLVM module into which output is inserted 99 1.1 joerg llvm::Module &TheModule; 100 1.1 joerg /// strut objc_super. Used for sending messages to super. This structure 101 1.1 joerg /// contains the receiver (object) and the expected class. 102 1.1 joerg llvm::StructType *ObjCSuperTy; 103 1.1 joerg /// struct objc_super*. The type of the argument to the superclass message 104 1.1 joerg /// lookup functions. 105 1.1 joerg llvm::PointerType *PtrToObjCSuperTy; 106 1.1 joerg /// LLVM type for selectors. Opaque pointer (i8*) unless a header declaring 107 1.1 joerg /// SEL is included in a header somewhere, in which case it will be whatever 108 1.1 joerg /// type is declared in that header, most likely {i8*, i8*}. 109 1.1 joerg llvm::PointerType *SelectorTy; 110 1.1 joerg /// LLVM i8 type. Cached here to avoid repeatedly getting it in all of the 111 1.1 joerg /// places where it's used 112 1.1 joerg llvm::IntegerType *Int8Ty; 113 1.1 joerg /// Pointer to i8 - LLVM type of char*, for all of the places where the 114 1.1 joerg /// runtime needs to deal with C strings. 115 1.1 joerg llvm::PointerType *PtrToInt8Ty; 116 1.1 joerg /// struct objc_protocol type 117 1.1 joerg llvm::StructType *ProtocolTy; 118 1.1 joerg /// Protocol * type. 119 1.1 joerg llvm::PointerType *ProtocolPtrTy; 120 1.1 joerg /// Instance Method Pointer type. This is a pointer to a function that takes, 121 1.1 joerg /// at a minimum, an object and a selector, and is the generic type for 122 1.1 joerg /// Objective-C methods. Due to differences between variadic / non-variadic 123 1.1 joerg /// calling conventions, it must always be cast to the correct type before 124 1.1 joerg /// actually being used. 125 1.1 joerg llvm::PointerType *IMPTy; 126 1.1 joerg /// Type of an untyped Objective-C object. Clang treats id as a built-in type 127 1.1 joerg /// when compiling Objective-C code, so this may be an opaque pointer (i8*), 128 1.1 joerg /// but if the runtime header declaring it is included then it may be a 129 1.1 joerg /// pointer to a structure. 130 1.1 joerg llvm::PointerType *IdTy; 131 1.1 joerg /// Pointer to a pointer to an Objective-C object. Used in the new ABI 132 1.1 joerg /// message lookup function and some GC-related functions. 133 1.1 joerg llvm::PointerType *PtrToIdTy; 134 1.1 joerg /// The clang type of id. Used when using the clang CGCall infrastructure to 135 1.1 joerg /// call Objective-C methods. 136 1.1 joerg CanQualType ASTIdTy; 137 1.1 joerg /// LLVM type for C int type. 138 1.1 joerg llvm::IntegerType *IntTy; 139 1.1 joerg /// LLVM type for an opaque pointer. This is identical to PtrToInt8Ty, but is 140 1.1 joerg /// used in the code to document the difference between i8* meaning a pointer 141 1.1 joerg /// to a C string and i8* meaning a pointer to some opaque type. 142 1.1 joerg llvm::PointerType *PtrTy; 143 1.1 joerg /// LLVM type for C long type. The runtime uses this in a lot of places where 144 1.1 joerg /// it should be using intptr_t, but we can't fix this without breaking 145 1.1 joerg /// compatibility with GCC... 146 1.1 joerg llvm::IntegerType *LongTy; 147 1.1 joerg /// LLVM type for C size_t. Used in various runtime data structures. 148 1.1 joerg llvm::IntegerType *SizeTy; 149 1.1 joerg /// LLVM type for C intptr_t. 150 1.1 joerg llvm::IntegerType *IntPtrTy; 151 1.1 joerg /// LLVM type for C ptrdiff_t. Mainly used in property accessor functions. 152 1.1 joerg llvm::IntegerType *PtrDiffTy; 153 1.1 joerg /// LLVM type for C int*. Used for GCC-ABI-compatible non-fragile instance 154 1.1 joerg /// variables. 155 1.1 joerg llvm::PointerType *PtrToIntTy; 156 1.1 joerg /// LLVM type for Objective-C BOOL type. 157 1.1 joerg llvm::Type *BoolTy; 158 1.1 joerg /// 32-bit integer type, to save us needing to look it up every time it's used. 159 1.1 joerg llvm::IntegerType *Int32Ty; 160 1.1 joerg /// 64-bit integer type, to save us needing to look it up every time it's used. 161 1.1 joerg llvm::IntegerType *Int64Ty; 162 1.1 joerg /// The type of struct objc_property. 163 1.1 joerg llvm::StructType *PropertyMetadataTy; 164 1.1 joerg /// Metadata kind used to tie method lookups to message sends. The GNUstep 165 1.1 joerg /// runtime provides some LLVM passes that can use this to do things like 166 1.1 joerg /// automatic IMP caching and speculative inlining. 167 1.1 joerg unsigned msgSendMDKind; 168 1.1 joerg /// Does the current target use SEH-based exceptions? False implies 169 1.1 joerg /// Itanium-style DWARF unwinding. 170 1.1 joerg bool usesSEHExceptions; 171 1.1 joerg 172 1.1 joerg /// Helper to check if we are targeting a specific runtime version or later. 173 1.1 joerg bool isRuntime(ObjCRuntime::Kind kind, unsigned major, unsigned minor=0) { 174 1.1 joerg const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime; 175 1.1 joerg return (R.getKind() == kind) && 176 1.1 joerg (R.getVersion() >= VersionTuple(major, minor)); 177 1.1 joerg } 178 1.1 joerg 179 1.1 joerg std::string ManglePublicSymbol(StringRef Name) { 180 1.1 joerg return (StringRef(CGM.getTriple().isOSBinFormatCOFF() ? "$_" : "._") + Name).str(); 181 1.1 joerg } 182 1.1 joerg 183 1.1 joerg std::string SymbolForProtocol(Twine Name) { 184 1.1 joerg return (ManglePublicSymbol("OBJC_PROTOCOL_") + Name).str(); 185 1.1 joerg } 186 1.1 joerg 187 1.1 joerg std::string SymbolForProtocolRef(StringRef Name) { 188 1.1 joerg return (ManglePublicSymbol("OBJC_REF_PROTOCOL_") + Name).str(); 189 1.1 joerg } 190 1.1 joerg 191 1.1 joerg 192 1.1 joerg /// Helper function that generates a constant string and returns a pointer to 193 1.1 joerg /// the start of the string. The result of this function can be used anywhere 194 1.1 joerg /// where the C code specifies const char*. 195 1.1 joerg llvm::Constant *MakeConstantString(StringRef Str, const char *Name = "") { 196 1.1.1.2 joerg ConstantAddress Array = 197 1.1.1.2 joerg CGM.GetAddrOfConstantCString(std::string(Str), Name); 198 1.1 joerg return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(), 199 1.1 joerg Array.getPointer(), Zeros); 200 1.1 joerg } 201 1.1 joerg 202 1.1 joerg /// Emits a linkonce_odr string, whose name is the prefix followed by the 203 1.1 joerg /// string value. This allows the linker to combine the strings between 204 1.1 joerg /// different modules. Used for EH typeinfo names, selector strings, and a 205 1.1 joerg /// few other things. 206 1.1 joerg llvm::Constant *ExportUniqueString(const std::string &Str, 207 1.1 joerg const std::string &prefix, 208 1.1 joerg bool Private=false) { 209 1.1 joerg std::string name = prefix + Str; 210 1.1 joerg auto *ConstStr = TheModule.getGlobalVariable(name); 211 1.1 joerg if (!ConstStr) { 212 1.1 joerg llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str); 213 1.1 joerg auto *GV = new llvm::GlobalVariable(TheModule, value->getType(), true, 214 1.1 joerg llvm::GlobalValue::LinkOnceODRLinkage, value, name); 215 1.1 joerg GV->setComdat(TheModule.getOrInsertComdat(name)); 216 1.1 joerg if (Private) 217 1.1 joerg GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 218 1.1 joerg ConstStr = GV; 219 1.1 joerg } 220 1.1 joerg return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(), 221 1.1 joerg ConstStr, Zeros); 222 1.1 joerg } 223 1.1 joerg 224 1.1 joerg /// Returns a property name and encoding string. 225 1.1 joerg llvm::Constant *MakePropertyEncodingString(const ObjCPropertyDecl *PD, 226 1.1 joerg const Decl *Container) { 227 1.1 joerg assert(!isRuntime(ObjCRuntime::GNUstep, 2)); 228 1.1 joerg if (isRuntime(ObjCRuntime::GNUstep, 1, 6)) { 229 1.1 joerg std::string NameAndAttributes; 230 1.1 joerg std::string TypeStr = 231 1.1 joerg CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); 232 1.1 joerg NameAndAttributes += '\0'; 233 1.1 joerg NameAndAttributes += TypeStr.length() + 3; 234 1.1 joerg NameAndAttributes += TypeStr; 235 1.1 joerg NameAndAttributes += '\0'; 236 1.1 joerg NameAndAttributes += PD->getNameAsString(); 237 1.1 joerg return MakeConstantString(NameAndAttributes); 238 1.1 joerg } 239 1.1 joerg return MakeConstantString(PD->getNameAsString()); 240 1.1 joerg } 241 1.1 joerg 242 1.1 joerg /// Push the property attributes into two structure fields. 243 1.1 joerg void PushPropertyAttributes(ConstantStructBuilder &Fields, 244 1.1 joerg const ObjCPropertyDecl *property, bool isSynthesized=true, bool 245 1.1 joerg isDynamic=true) { 246 1.1 joerg int attrs = property->getPropertyAttributes(); 247 1.1 joerg // For read-only properties, clear the copy and retain flags 248 1.1.1.2 joerg if (attrs & ObjCPropertyAttribute::kind_readonly) { 249 1.1.1.2 joerg attrs &= ~ObjCPropertyAttribute::kind_copy; 250 1.1.1.2 joerg attrs &= ~ObjCPropertyAttribute::kind_retain; 251 1.1.1.2 joerg attrs &= ~ObjCPropertyAttribute::kind_weak; 252 1.1.1.2 joerg attrs &= ~ObjCPropertyAttribute::kind_strong; 253 1.1 joerg } 254 1.1 joerg // The first flags field has the same attribute values as clang uses internally 255 1.1 joerg Fields.addInt(Int8Ty, attrs & 0xff); 256 1.1 joerg attrs >>= 8; 257 1.1 joerg attrs <<= 2; 258 1.1 joerg // For protocol properties, synthesized and dynamic have no meaning, so we 259 1.1 joerg // reuse these flags to indicate that this is a protocol property (both set 260 1.1 joerg // has no meaning, as a property can't be both synthesized and dynamic) 261 1.1 joerg attrs |= isSynthesized ? (1<<0) : 0; 262 1.1 joerg attrs |= isDynamic ? (1<<1) : 0; 263 1.1 joerg // The second field is the next four fields left shifted by two, with the 264 1.1 joerg // low bit set to indicate whether the field is synthesized or dynamic. 265 1.1 joerg Fields.addInt(Int8Ty, attrs & 0xff); 266 1.1 joerg // Two padding fields 267 1.1 joerg Fields.addInt(Int8Ty, 0); 268 1.1 joerg Fields.addInt(Int8Ty, 0); 269 1.1 joerg } 270 1.1 joerg 271 1.1 joerg virtual llvm::Constant *GenerateCategoryProtocolList(const 272 1.1 joerg ObjCCategoryDecl *OCD); 273 1.1 joerg virtual ConstantArrayBuilder PushPropertyListHeader(ConstantStructBuilder &Fields, 274 1.1 joerg int count) { 275 1.1 joerg // int count; 276 1.1 joerg Fields.addInt(IntTy, count); 277 1.1 joerg // int size; (only in GNUstep v2 ABI. 278 1.1 joerg if (isRuntime(ObjCRuntime::GNUstep, 2)) { 279 1.1 joerg llvm::DataLayout td(&TheModule); 280 1.1 joerg Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) / 281 1.1 joerg CGM.getContext().getCharWidth()); 282 1.1 joerg } 283 1.1 joerg // struct objc_property_list *next; 284 1.1 joerg Fields.add(NULLPtr); 285 1.1 joerg // struct objc_property properties[] 286 1.1 joerg return Fields.beginArray(PropertyMetadataTy); 287 1.1 joerg } 288 1.1 joerg virtual void PushProperty(ConstantArrayBuilder &PropertiesArray, 289 1.1 joerg const ObjCPropertyDecl *property, 290 1.1 joerg const Decl *OCD, 291 1.1 joerg bool isSynthesized=true, bool 292 1.1 joerg isDynamic=true) { 293 1.1 joerg auto Fields = PropertiesArray.beginStruct(PropertyMetadataTy); 294 1.1 joerg ASTContext &Context = CGM.getContext(); 295 1.1 joerg Fields.add(MakePropertyEncodingString(property, OCD)); 296 1.1 joerg PushPropertyAttributes(Fields, property, isSynthesized, isDynamic); 297 1.1 joerg auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) { 298 1.1 joerg if (accessor) { 299 1.1 joerg std::string TypeStr = Context.getObjCEncodingForMethodDecl(accessor); 300 1.1 joerg llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 301 1.1 joerg Fields.add(MakeConstantString(accessor->getSelector().getAsString())); 302 1.1 joerg Fields.add(TypeEncoding); 303 1.1 joerg } else { 304 1.1 joerg Fields.add(NULLPtr); 305 1.1 joerg Fields.add(NULLPtr); 306 1.1 joerg } 307 1.1 joerg }; 308 1.1 joerg addPropertyMethod(property->getGetterMethodDecl()); 309 1.1 joerg addPropertyMethod(property->getSetterMethodDecl()); 310 1.1 joerg Fields.finishAndAddTo(PropertiesArray); 311 1.1 joerg } 312 1.1 joerg 313 1.1 joerg /// Ensures that the value has the required type, by inserting a bitcast if 314 1.1 joerg /// required. This function lets us avoid inserting bitcasts that are 315 1.1 joerg /// redundant. 316 1.1 joerg llvm::Value* EnforceType(CGBuilderTy &B, llvm::Value *V, llvm::Type *Ty) { 317 1.1 joerg if (V->getType() == Ty) return V; 318 1.1 joerg return B.CreateBitCast(V, Ty); 319 1.1 joerg } 320 1.1 joerg Address EnforceType(CGBuilderTy &B, Address V, llvm::Type *Ty) { 321 1.1 joerg if (V.getType() == Ty) return V; 322 1.1 joerg return B.CreateBitCast(V, Ty); 323 1.1 joerg } 324 1.1 joerg 325 1.1 joerg // Some zeros used for GEPs in lots of places. 326 1.1 joerg llvm::Constant *Zeros[2]; 327 1.1 joerg /// Null pointer value. Mainly used as a terminator in various arrays. 328 1.1 joerg llvm::Constant *NULLPtr; 329 1.1 joerg /// LLVM context. 330 1.1 joerg llvm::LLVMContext &VMContext; 331 1.1 joerg 332 1.1 joerg protected: 333 1.1 joerg 334 1.1 joerg /// Placeholder for the class. Lots of things refer to the class before we've 335 1.1 joerg /// actually emitted it. We use this alias as a placeholder, and then replace 336 1.1 joerg /// it with a pointer to the class structure before finally emitting the 337 1.1 joerg /// module. 338 1.1 joerg llvm::GlobalAlias *ClassPtrAlias; 339 1.1 joerg /// Placeholder for the metaclass. Lots of things refer to the class before 340 1.1 joerg /// we've / actually emitted it. We use this alias as a placeholder, and then 341 1.1 joerg /// replace / it with a pointer to the metaclass structure before finally 342 1.1 joerg /// emitting the / module. 343 1.1 joerg llvm::GlobalAlias *MetaClassPtrAlias; 344 1.1 joerg /// All of the classes that have been generated for this compilation units. 345 1.1 joerg std::vector<llvm::Constant*> Classes; 346 1.1 joerg /// All of the categories that have been generated for this compilation units. 347 1.1 joerg std::vector<llvm::Constant*> Categories; 348 1.1 joerg /// All of the Objective-C constant strings that have been generated for this 349 1.1 joerg /// compilation units. 350 1.1 joerg std::vector<llvm::Constant*> ConstantStrings; 351 1.1 joerg /// Map from string values to Objective-C constant strings in the output. 352 1.1 joerg /// Used to prevent emitting Objective-C strings more than once. This should 353 1.1 joerg /// not be required at all - CodeGenModule should manage this list. 354 1.1 joerg llvm::StringMap<llvm::Constant*> ObjCStrings; 355 1.1 joerg /// All of the protocols that have been declared. 356 1.1 joerg llvm::StringMap<llvm::Constant*> ExistingProtocols; 357 1.1 joerg /// For each variant of a selector, we store the type encoding and a 358 1.1 joerg /// placeholder value. For an untyped selector, the type will be the empty 359 1.1 joerg /// string. Selector references are all done via the module's selector table, 360 1.1 joerg /// so we create an alias as a placeholder and then replace it with the real 361 1.1 joerg /// value later. 362 1.1 joerg typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector; 363 1.1 joerg /// Type of the selector map. This is roughly equivalent to the structure 364 1.1 joerg /// used in the GNUstep runtime, which maintains a list of all of the valid 365 1.1 joerg /// types for a selector in a table. 366 1.1 joerg typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> > 367 1.1 joerg SelectorMap; 368 1.1 joerg /// A map from selectors to selector types. This allows us to emit all 369 1.1 joerg /// selectors of the same name and type together. 370 1.1 joerg SelectorMap SelectorTable; 371 1.1 joerg 372 1.1 joerg /// Selectors related to memory management. When compiling in GC mode, we 373 1.1 joerg /// omit these. 374 1.1 joerg Selector RetainSel, ReleaseSel, AutoreleaseSel; 375 1.1 joerg /// Runtime functions used for memory management in GC mode. Note that clang 376 1.1 joerg /// supports code generation for calling these functions, but neither GNU 377 1.1 joerg /// runtime actually supports this API properly yet. 378 1.1 joerg LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn, 379 1.1 joerg WeakAssignFn, GlobalAssignFn; 380 1.1 joerg 381 1.1 joerg typedef std::pair<std::string, std::string> ClassAliasPair; 382 1.1 joerg /// All classes that have aliases set for them. 383 1.1 joerg std::vector<ClassAliasPair> ClassAliases; 384 1.1 joerg 385 1.1 joerg protected: 386 1.1 joerg /// Function used for throwing Objective-C exceptions. 387 1.1 joerg LazyRuntimeFunction ExceptionThrowFn; 388 1.1 joerg /// Function used for rethrowing exceptions, used at the end of \@finally or 389 1.1 joerg /// \@synchronize blocks. 390 1.1 joerg LazyRuntimeFunction ExceptionReThrowFn; 391 1.1 joerg /// Function called when entering a catch function. This is required for 392 1.1 joerg /// differentiating Objective-C exceptions and foreign exceptions. 393 1.1 joerg LazyRuntimeFunction EnterCatchFn; 394 1.1 joerg /// Function called when exiting from a catch block. Used to do exception 395 1.1 joerg /// cleanup. 396 1.1 joerg LazyRuntimeFunction ExitCatchFn; 397 1.1 joerg /// Function called when entering an \@synchronize block. Acquires the lock. 398 1.1 joerg LazyRuntimeFunction SyncEnterFn; 399 1.1 joerg /// Function called when exiting an \@synchronize block. Releases the lock. 400 1.1 joerg LazyRuntimeFunction SyncExitFn; 401 1.1 joerg 402 1.1 joerg private: 403 1.1 joerg /// Function called if fast enumeration detects that the collection is 404 1.1 joerg /// modified during the update. 405 1.1 joerg LazyRuntimeFunction EnumerationMutationFn; 406 1.1 joerg /// Function for implementing synthesized property getters that return an 407 1.1 joerg /// object. 408 1.1 joerg LazyRuntimeFunction GetPropertyFn; 409 1.1 joerg /// Function for implementing synthesized property setters that return an 410 1.1 joerg /// object. 411 1.1 joerg LazyRuntimeFunction SetPropertyFn; 412 1.1 joerg /// Function used for non-object declared property getters. 413 1.1 joerg LazyRuntimeFunction GetStructPropertyFn; 414 1.1 joerg /// Function used for non-object declared property setters. 415 1.1 joerg LazyRuntimeFunction SetStructPropertyFn; 416 1.1 joerg 417 1.1 joerg protected: 418 1.1 joerg /// The version of the runtime that this class targets. Must match the 419 1.1 joerg /// version in the runtime. 420 1.1 joerg int RuntimeVersion; 421 1.1 joerg /// The version of the protocol class. Used to differentiate between ObjC1 422 1.1 joerg /// and ObjC2 protocols. Objective-C 1 protocols can not contain optional 423 1.1 joerg /// components and can not contain declared properties. We always emit 424 1.1 joerg /// Objective-C 2 property structures, but we have to pretend that they're 425 1.1 joerg /// Objective-C 1 property structures when targeting the GCC runtime or it 426 1.1 joerg /// will abort. 427 1.1 joerg const int ProtocolVersion; 428 1.1 joerg /// The version of the class ABI. This value is used in the class structure 429 1.1 joerg /// and indicates how various fields should be interpreted. 430 1.1 joerg const int ClassABIVersion; 431 1.1 joerg /// Generates an instance variable list structure. This is a structure 432 1.1 joerg /// containing a size and an array of structures containing instance variable 433 1.1 joerg /// metadata. This is used purely for introspection in the fragile ABI. In 434 1.1 joerg /// the non-fragile ABI, it's used for instance variable fixup. 435 1.1 joerg virtual llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames, 436 1.1 joerg ArrayRef<llvm::Constant *> IvarTypes, 437 1.1 joerg ArrayRef<llvm::Constant *> IvarOffsets, 438 1.1 joerg ArrayRef<llvm::Constant *> IvarAlign, 439 1.1 joerg ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership); 440 1.1 joerg 441 1.1 joerg /// Generates a method list structure. This is a structure containing a size 442 1.1 joerg /// and an array of structures containing method metadata. 443 1.1 joerg /// 444 1.1 joerg /// This structure is used by both classes and categories, and contains a next 445 1.1 joerg /// pointer allowing them to be chained together in a linked list. 446 1.1 joerg llvm::Constant *GenerateMethodList(StringRef ClassName, 447 1.1 joerg StringRef CategoryName, 448 1.1 joerg ArrayRef<const ObjCMethodDecl*> Methods, 449 1.1 joerg bool isClassMethodList); 450 1.1 joerg 451 1.1 joerg /// Emits an empty protocol. This is used for \@protocol() where no protocol 452 1.1 joerg /// is found. The runtime will (hopefully) fix up the pointer to refer to the 453 1.1 joerg /// real protocol. 454 1.1 joerg virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName); 455 1.1 joerg 456 1.1 joerg /// Generates a list of property metadata structures. This follows the same 457 1.1 joerg /// pattern as method and instance variable metadata lists. 458 1.1 joerg llvm::Constant *GeneratePropertyList(const Decl *Container, 459 1.1 joerg const ObjCContainerDecl *OCD, 460 1.1 joerg bool isClassProperty=false, 461 1.1 joerg bool protocolOptionalProperties=false); 462 1.1 joerg 463 1.1 joerg /// Generates a list of referenced protocols. Classes, categories, and 464 1.1 joerg /// protocols all use this structure. 465 1.1 joerg llvm::Constant *GenerateProtocolList(ArrayRef<std::string> Protocols); 466 1.1 joerg 467 1.1 joerg /// To ensure that all protocols are seen by the runtime, we add a category on 468 1.1 joerg /// a class defined in the runtime, declaring no methods, but adopting the 469 1.1 joerg /// protocols. This is a horribly ugly hack, but it allows us to collect all 470 1.1 joerg /// of the protocols without changing the ABI. 471 1.1 joerg void GenerateProtocolHolderCategory(); 472 1.1 joerg 473 1.1 joerg /// Generates a class structure. 474 1.1 joerg llvm::Constant *GenerateClassStructure( 475 1.1 joerg llvm::Constant *MetaClass, 476 1.1 joerg llvm::Constant *SuperClass, 477 1.1 joerg unsigned info, 478 1.1 joerg const char *Name, 479 1.1 joerg llvm::Constant *Version, 480 1.1 joerg llvm::Constant *InstanceSize, 481 1.1 joerg llvm::Constant *IVars, 482 1.1 joerg llvm::Constant *Methods, 483 1.1 joerg llvm::Constant *Protocols, 484 1.1 joerg llvm::Constant *IvarOffsets, 485 1.1 joerg llvm::Constant *Properties, 486 1.1 joerg llvm::Constant *StrongIvarBitmap, 487 1.1 joerg llvm::Constant *WeakIvarBitmap, 488 1.1 joerg bool isMeta=false); 489 1.1 joerg 490 1.1 joerg /// Generates a method list. This is used by protocols to define the required 491 1.1 joerg /// and optional methods. 492 1.1 joerg virtual llvm::Constant *GenerateProtocolMethodList( 493 1.1 joerg ArrayRef<const ObjCMethodDecl*> Methods); 494 1.1 joerg /// Emits optional and required method lists. 495 1.1 joerg template<class T> 496 1.1 joerg void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required, 497 1.1 joerg llvm::Constant *&Optional) { 498 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> RequiredMethods; 499 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> OptionalMethods; 500 1.1 joerg for (const auto *I : Methods) 501 1.1 joerg if (I->isOptional()) 502 1.1 joerg OptionalMethods.push_back(I); 503 1.1 joerg else 504 1.1 joerg RequiredMethods.push_back(I); 505 1.1 joerg Required = GenerateProtocolMethodList(RequiredMethods); 506 1.1 joerg Optional = GenerateProtocolMethodList(OptionalMethods); 507 1.1 joerg } 508 1.1 joerg 509 1.1 joerg /// Returns a selector with the specified type encoding. An empty string is 510 1.1 joerg /// used to return an untyped selector (with the types field set to NULL). 511 1.1 joerg virtual llvm::Value *GetTypedSelector(CodeGenFunction &CGF, Selector Sel, 512 1.1 joerg const std::string &TypeEncoding); 513 1.1 joerg 514 1.1 joerg /// Returns the name of ivar offset variables. In the GNUstep v1 ABI, this 515 1.1 joerg /// contains the class and ivar names, in the v2 ABI this contains the type 516 1.1 joerg /// encoding as well. 517 1.1 joerg virtual std::string GetIVarOffsetVariableName(const ObjCInterfaceDecl *ID, 518 1.1 joerg const ObjCIvarDecl *Ivar) { 519 1.1 joerg const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() 520 1.1 joerg + '.' + Ivar->getNameAsString(); 521 1.1 joerg return Name; 522 1.1 joerg } 523 1.1 joerg /// Returns the variable used to store the offset of an instance variable. 524 1.1 joerg llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 525 1.1 joerg const ObjCIvarDecl *Ivar); 526 1.1 joerg /// Emits a reference to a class. This allows the linker to object if there 527 1.1 joerg /// is no class of the matching name. 528 1.1 joerg void EmitClassRef(const std::string &className); 529 1.1 joerg 530 1.1 joerg /// Emits a pointer to the named class 531 1.1 joerg virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF, 532 1.1 joerg const std::string &Name, bool isWeak); 533 1.1 joerg 534 1.1 joerg /// Looks up the method for sending a message to the specified object. This 535 1.1 joerg /// mechanism differs between the GCC and GNU runtimes, so this method must be 536 1.1 joerg /// overridden in subclasses. 537 1.1 joerg virtual llvm::Value *LookupIMP(CodeGenFunction &CGF, 538 1.1 joerg llvm::Value *&Receiver, 539 1.1 joerg llvm::Value *cmd, 540 1.1 joerg llvm::MDNode *node, 541 1.1 joerg MessageSendInfo &MSI) = 0; 542 1.1 joerg 543 1.1 joerg /// Looks up the method for sending a message to a superclass. This 544 1.1 joerg /// mechanism differs between the GCC and GNU runtimes, so this method must 545 1.1 joerg /// be overridden in subclasses. 546 1.1 joerg virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, 547 1.1 joerg Address ObjCSuper, 548 1.1 joerg llvm::Value *cmd, 549 1.1 joerg MessageSendInfo &MSI) = 0; 550 1.1 joerg 551 1.1 joerg /// Libobjc2 uses a bitfield representation where small(ish) bitfields are 552 1.1 joerg /// stored in a 64-bit value with the low bit set to 1 and the remaining 63 553 1.1 joerg /// bits set to their values, LSB first, while larger ones are stored in a 554 1.1 joerg /// structure of this / form: 555 1.1 joerg /// 556 1.1 joerg /// struct { int32_t length; int32_t values[length]; }; 557 1.1 joerg /// 558 1.1 joerg /// The values in the array are stored in host-endian format, with the least 559 1.1 joerg /// significant bit being assumed to come first in the bitfield. Therefore, 560 1.1 joerg /// a bitfield with the 64th bit set will be (int64_t)&{ 2, [0, 1<<31] }, 561 1.1 joerg /// while a bitfield / with the 63rd bit set will be 1<<64. 562 1.1 joerg llvm::Constant *MakeBitField(ArrayRef<bool> bits); 563 1.1 joerg 564 1.1 joerg public: 565 1.1 joerg CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion, 566 1.1 joerg unsigned protocolClassVersion, unsigned classABI=1); 567 1.1 joerg 568 1.1 joerg ConstantAddress GenerateConstantString(const StringLiteral *) override; 569 1.1 joerg 570 1.1 joerg RValue 571 1.1 joerg GenerateMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return, 572 1.1 joerg QualType ResultType, Selector Sel, 573 1.1 joerg llvm::Value *Receiver, const CallArgList &CallArgs, 574 1.1 joerg const ObjCInterfaceDecl *Class, 575 1.1 joerg const ObjCMethodDecl *Method) override; 576 1.1 joerg RValue 577 1.1 joerg GenerateMessageSendSuper(CodeGenFunction &CGF, ReturnValueSlot Return, 578 1.1 joerg QualType ResultType, Selector Sel, 579 1.1 joerg const ObjCInterfaceDecl *Class, 580 1.1 joerg bool isCategoryImpl, llvm::Value *Receiver, 581 1.1 joerg bool IsClassMessage, const CallArgList &CallArgs, 582 1.1 joerg const ObjCMethodDecl *Method) override; 583 1.1 joerg llvm::Value *GetClass(CodeGenFunction &CGF, 584 1.1 joerg const ObjCInterfaceDecl *OID) override; 585 1.1 joerg llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override; 586 1.1 joerg Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override; 587 1.1 joerg llvm::Value *GetSelector(CodeGenFunction &CGF, 588 1.1 joerg const ObjCMethodDecl *Method) override; 589 1.1 joerg virtual llvm::Constant *GetConstantSelector(Selector Sel, 590 1.1 joerg const std::string &TypeEncoding) { 591 1.1 joerg llvm_unreachable("Runtime unable to generate constant selector"); 592 1.1 joerg } 593 1.1 joerg llvm::Constant *GetConstantSelector(const ObjCMethodDecl *M) { 594 1.1 joerg return GetConstantSelector(M->getSelector(), 595 1.1 joerg CGM.getContext().getObjCEncodingForMethodDecl(M)); 596 1.1 joerg } 597 1.1 joerg llvm::Constant *GetEHType(QualType T) override; 598 1.1 joerg 599 1.1 joerg llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 600 1.1 joerg const ObjCContainerDecl *CD) override; 601 1.1.1.2 joerg void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, 602 1.1.1.2 joerg const ObjCMethodDecl *OMD, 603 1.1.1.2 joerg const ObjCContainerDecl *CD) override; 604 1.1 joerg void GenerateCategory(const ObjCCategoryImplDecl *CMD) override; 605 1.1 joerg void GenerateClass(const ObjCImplementationDecl *ClassDecl) override; 606 1.1 joerg void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override; 607 1.1 joerg llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, 608 1.1 joerg const ObjCProtocolDecl *PD) override; 609 1.1 joerg void GenerateProtocol(const ObjCProtocolDecl *PD) override; 610 1.1.1.2 joerg 611 1.1.1.2 joerg virtual llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD); 612 1.1.1.2 joerg 613 1.1.1.2 joerg llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override { 614 1.1.1.2 joerg return GenerateProtocolRef(PD); 615 1.1.1.2 joerg } 616 1.1.1.2 joerg 617 1.1 joerg llvm::Function *ModuleInitFunction() override; 618 1.1 joerg llvm::FunctionCallee GetPropertyGetFunction() override; 619 1.1 joerg llvm::FunctionCallee GetPropertySetFunction() override; 620 1.1 joerg llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, 621 1.1 joerg bool copy) override; 622 1.1 joerg llvm::FunctionCallee GetSetStructFunction() override; 623 1.1 joerg llvm::FunctionCallee GetGetStructFunction() override; 624 1.1 joerg llvm::FunctionCallee GetCppAtomicObjectGetFunction() override; 625 1.1 joerg llvm::FunctionCallee GetCppAtomicObjectSetFunction() override; 626 1.1 joerg llvm::FunctionCallee EnumerationMutationFunction() override; 627 1.1 joerg 628 1.1 joerg void EmitTryStmt(CodeGenFunction &CGF, 629 1.1 joerg const ObjCAtTryStmt &S) override; 630 1.1 joerg void EmitSynchronizedStmt(CodeGenFunction &CGF, 631 1.1 joerg const ObjCAtSynchronizedStmt &S) override; 632 1.1 joerg void EmitThrowStmt(CodeGenFunction &CGF, 633 1.1 joerg const ObjCAtThrowStmt &S, 634 1.1 joerg bool ClearInsertionPoint=true) override; 635 1.1 joerg llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF, 636 1.1 joerg Address AddrWeakObj) override; 637 1.1 joerg void EmitObjCWeakAssign(CodeGenFunction &CGF, 638 1.1 joerg llvm::Value *src, Address dst) override; 639 1.1 joerg void EmitObjCGlobalAssign(CodeGenFunction &CGF, 640 1.1 joerg llvm::Value *src, Address dest, 641 1.1 joerg bool threadlocal=false) override; 642 1.1 joerg void EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *src, 643 1.1 joerg Address dest, llvm::Value *ivarOffset) override; 644 1.1 joerg void EmitObjCStrongCastAssign(CodeGenFunction &CGF, 645 1.1 joerg llvm::Value *src, Address dest) override; 646 1.1 joerg void EmitGCMemmoveCollectable(CodeGenFunction &CGF, Address DestPtr, 647 1.1 joerg Address SrcPtr, 648 1.1 joerg llvm::Value *Size) override; 649 1.1 joerg LValue EmitObjCValueForIvar(CodeGenFunction &CGF, QualType ObjectTy, 650 1.1 joerg llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, 651 1.1 joerg unsigned CVRQualifiers) override; 652 1.1 joerg llvm::Value *EmitIvarOffset(CodeGenFunction &CGF, 653 1.1 joerg const ObjCInterfaceDecl *Interface, 654 1.1 joerg const ObjCIvarDecl *Ivar) override; 655 1.1 joerg llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override; 656 1.1 joerg llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM, 657 1.1 joerg const CGBlockInfo &blockInfo) override { 658 1.1 joerg return NULLPtr; 659 1.1 joerg } 660 1.1 joerg llvm::Constant *BuildRCBlockLayout(CodeGenModule &CGM, 661 1.1 joerg const CGBlockInfo &blockInfo) override { 662 1.1 joerg return NULLPtr; 663 1.1 joerg } 664 1.1 joerg 665 1.1 joerg llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, QualType T) override { 666 1.1 joerg return NULLPtr; 667 1.1 joerg } 668 1.1 joerg }; 669 1.1 joerg 670 1.1 joerg /// Class representing the legacy GCC Objective-C ABI. This is the default when 671 1.1 joerg /// -fobjc-nonfragile-abi is not specified. 672 1.1 joerg /// 673 1.1 joerg /// The GCC ABI target actually generates code that is approximately compatible 674 1.1 joerg /// with the new GNUstep runtime ABI, but refrains from using any features that 675 1.1 joerg /// would not work with the GCC runtime. For example, clang always generates 676 1.1 joerg /// the extended form of the class structure, and the extra fields are simply 677 1.1 joerg /// ignored by GCC libobjc. 678 1.1 joerg class CGObjCGCC : public CGObjCGNU { 679 1.1 joerg /// The GCC ABI message lookup function. Returns an IMP pointing to the 680 1.1 joerg /// method implementation for this message. 681 1.1 joerg LazyRuntimeFunction MsgLookupFn; 682 1.1 joerg /// The GCC ABI superclass message lookup function. Takes a pointer to a 683 1.1 joerg /// structure describing the receiver and the class, and a selector as 684 1.1 joerg /// arguments. Returns the IMP for the corresponding method. 685 1.1 joerg LazyRuntimeFunction MsgLookupSuperFn; 686 1.1 joerg 687 1.1 joerg protected: 688 1.1 joerg llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, 689 1.1 joerg llvm::Value *cmd, llvm::MDNode *node, 690 1.1 joerg MessageSendInfo &MSI) override { 691 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 692 1.1 joerg llvm::Value *args[] = { 693 1.1 joerg EnforceType(Builder, Receiver, IdTy), 694 1.1 joerg EnforceType(Builder, cmd, SelectorTy) }; 695 1.1 joerg llvm::CallBase *imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); 696 1.1 joerg imp->setMetadata(msgSendMDKind, node); 697 1.1 joerg return imp; 698 1.1 joerg } 699 1.1 joerg 700 1.1 joerg llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, 701 1.1 joerg llvm::Value *cmd, MessageSendInfo &MSI) override { 702 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 703 1.1 joerg llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper, 704 1.1 joerg PtrToObjCSuperTy).getPointer(), cmd}; 705 1.1 joerg return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); 706 1.1 joerg } 707 1.1 joerg 708 1.1 joerg public: 709 1.1 joerg CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) { 710 1.1 joerg // IMP objc_msg_lookup(id, SEL); 711 1.1 joerg MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy); 712 1.1 joerg // IMP objc_msg_lookup_super(struct objc_super*, SEL); 713 1.1 joerg MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, 714 1.1 joerg PtrToObjCSuperTy, SelectorTy); 715 1.1 joerg } 716 1.1 joerg }; 717 1.1 joerg 718 1.1 joerg /// Class used when targeting the new GNUstep runtime ABI. 719 1.1 joerg class CGObjCGNUstep : public CGObjCGNU { 720 1.1 joerg /// The slot lookup function. Returns a pointer to a cacheable structure 721 1.1 joerg /// that contains (among other things) the IMP. 722 1.1 joerg LazyRuntimeFunction SlotLookupFn; 723 1.1 joerg /// The GNUstep ABI superclass message lookup function. Takes a pointer to 724 1.1 joerg /// a structure describing the receiver and the class, and a selector as 725 1.1 joerg /// arguments. Returns the slot for the corresponding method. Superclass 726 1.1 joerg /// message lookup rarely changes, so this is a good caching opportunity. 727 1.1 joerg LazyRuntimeFunction SlotLookupSuperFn; 728 1.1 joerg /// Specialised function for setting atomic retain properties 729 1.1 joerg LazyRuntimeFunction SetPropertyAtomic; 730 1.1 joerg /// Specialised function for setting atomic copy properties 731 1.1 joerg LazyRuntimeFunction SetPropertyAtomicCopy; 732 1.1 joerg /// Specialised function for setting nonatomic retain properties 733 1.1 joerg LazyRuntimeFunction SetPropertyNonAtomic; 734 1.1 joerg /// Specialised function for setting nonatomic copy properties 735 1.1 joerg LazyRuntimeFunction SetPropertyNonAtomicCopy; 736 1.1 joerg /// Function to perform atomic copies of C++ objects with nontrivial copy 737 1.1 joerg /// constructors from Objective-C ivars. 738 1.1 joerg LazyRuntimeFunction CxxAtomicObjectGetFn; 739 1.1 joerg /// Function to perform atomic copies of C++ objects with nontrivial copy 740 1.1 joerg /// constructors to Objective-C ivars. 741 1.1 joerg LazyRuntimeFunction CxxAtomicObjectSetFn; 742 1.1 joerg /// Type of an slot structure pointer. This is returned by the various 743 1.1 joerg /// lookup functions. 744 1.1 joerg llvm::Type *SlotTy; 745 1.1 joerg 746 1.1 joerg public: 747 1.1 joerg llvm::Constant *GetEHType(QualType T) override; 748 1.1 joerg 749 1.1 joerg protected: 750 1.1 joerg llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, 751 1.1 joerg llvm::Value *cmd, llvm::MDNode *node, 752 1.1 joerg MessageSendInfo &MSI) override { 753 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 754 1.1 joerg llvm::FunctionCallee LookupFn = SlotLookupFn; 755 1.1 joerg 756 1.1 joerg // Store the receiver on the stack so that we can reload it later 757 1.1 joerg Address ReceiverPtr = 758 1.1 joerg CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign()); 759 1.1 joerg Builder.CreateStore(Receiver, ReceiverPtr); 760 1.1 joerg 761 1.1 joerg llvm::Value *self; 762 1.1 joerg 763 1.1 joerg if (isa<ObjCMethodDecl>(CGF.CurCodeDecl)) { 764 1.1 joerg self = CGF.LoadObjCSelf(); 765 1.1 joerg } else { 766 1.1 joerg self = llvm::ConstantPointerNull::get(IdTy); 767 1.1 joerg } 768 1.1 joerg 769 1.1 joerg // The lookup function is guaranteed not to capture the receiver pointer. 770 1.1 joerg if (auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee())) 771 1.1 joerg LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture); 772 1.1 joerg 773 1.1 joerg llvm::Value *args[] = { 774 1.1 joerg EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), 775 1.1 joerg EnforceType(Builder, cmd, SelectorTy), 776 1.1 joerg EnforceType(Builder, self, IdTy) }; 777 1.1 joerg llvm::CallBase *slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); 778 1.1 joerg slot->setOnlyReadsMemory(); 779 1.1 joerg slot->setMetadata(msgSendMDKind, node); 780 1.1 joerg 781 1.1 joerg // Load the imp from the slot 782 1.1 joerg llvm::Value *imp = Builder.CreateAlignedLoad( 783 1.1.1.2 joerg IMPTy, Builder.CreateStructGEP(nullptr, slot, 4), 784 1.1.1.2 joerg CGF.getPointerAlign()); 785 1.1 joerg 786 1.1 joerg // The lookup function may have changed the receiver, so make sure we use 787 1.1 joerg // the new one. 788 1.1 joerg Receiver = Builder.CreateLoad(ReceiverPtr, true); 789 1.1 joerg return imp; 790 1.1 joerg } 791 1.1 joerg 792 1.1 joerg llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, 793 1.1 joerg llvm::Value *cmd, 794 1.1 joerg MessageSendInfo &MSI) override { 795 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 796 1.1 joerg llvm::Value *lookupArgs[] = {ObjCSuper.getPointer(), cmd}; 797 1.1 joerg 798 1.1 joerg llvm::CallInst *slot = 799 1.1 joerg CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs); 800 1.1 joerg slot->setOnlyReadsMemory(); 801 1.1 joerg 802 1.1.1.2 joerg return Builder.CreateAlignedLoad( 803 1.1.1.2 joerg IMPTy, Builder.CreateStructGEP(nullptr, slot, 4), 804 1.1.1.2 joerg CGF.getPointerAlign()); 805 1.1 joerg } 806 1.1 joerg 807 1.1 joerg public: 808 1.1 joerg CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {} 809 1.1 joerg CGObjCGNUstep(CodeGenModule &Mod, unsigned ABI, unsigned ProtocolABI, 810 1.1 joerg unsigned ClassABI) : 811 1.1 joerg CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) { 812 1.1 joerg const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime; 813 1.1 joerg 814 1.1 joerg llvm::StructType *SlotStructTy = 815 1.1 joerg llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy); 816 1.1 joerg SlotTy = llvm::PointerType::getUnqual(SlotStructTy); 817 1.1 joerg // Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender); 818 1.1 joerg SlotLookupFn.init(&CGM, "objc_msg_lookup_sender", SlotTy, PtrToIdTy, 819 1.1 joerg SelectorTy, IdTy); 820 1.1 joerg // Slot_t objc_slot_lookup_super(struct objc_super*, SEL); 821 1.1 joerg SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy, 822 1.1 joerg PtrToObjCSuperTy, SelectorTy); 823 1.1.1.2 joerg // If we're in ObjC++ mode, then we want to make 824 1.1 joerg if (usesSEHExceptions) { 825 1.1 joerg llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); 826 1.1 joerg // void objc_exception_rethrow(void) 827 1.1 joerg ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy); 828 1.1 joerg } else if (CGM.getLangOpts().CPlusPlus) { 829 1.1 joerg llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); 830 1.1 joerg // void *__cxa_begin_catch(void *e) 831 1.1 joerg EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy); 832 1.1 joerg // void __cxa_end_catch(void) 833 1.1 joerg ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy); 834 1.1 joerg // void _Unwind_Resume_or_Rethrow(void*) 835 1.1 joerg ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy, 836 1.1 joerg PtrTy); 837 1.1 joerg } else if (R.getVersion() >= VersionTuple(1, 7)) { 838 1.1 joerg llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); 839 1.1 joerg // id objc_begin_catch(void *e) 840 1.1 joerg EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy); 841 1.1 joerg // void objc_end_catch(void) 842 1.1 joerg ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy); 843 1.1 joerg // void _Unwind_Resume_or_Rethrow(void*) 844 1.1 joerg ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy, PtrTy); 845 1.1 joerg } 846 1.1 joerg llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); 847 1.1 joerg SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy, 848 1.1 joerg SelectorTy, IdTy, PtrDiffTy); 849 1.1 joerg SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy, 850 1.1 joerg IdTy, SelectorTy, IdTy, PtrDiffTy); 851 1.1 joerg SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy, 852 1.1 joerg IdTy, SelectorTy, IdTy, PtrDiffTy); 853 1.1 joerg SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy", 854 1.1 joerg VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy); 855 1.1 joerg // void objc_setCppObjectAtomic(void *dest, const void *src, void 856 1.1 joerg // *helper); 857 1.1 joerg CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy, 858 1.1 joerg PtrTy, PtrTy); 859 1.1 joerg // void objc_getCppObjectAtomic(void *dest, const void *src, void 860 1.1 joerg // *helper); 861 1.1 joerg CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy, 862 1.1 joerg PtrTy, PtrTy); 863 1.1 joerg } 864 1.1 joerg 865 1.1 joerg llvm::FunctionCallee GetCppAtomicObjectGetFunction() override { 866 1.1 joerg // The optimised functions were added in version 1.7 of the GNUstep 867 1.1 joerg // runtime. 868 1.1 joerg assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= 869 1.1 joerg VersionTuple(1, 7)); 870 1.1 joerg return CxxAtomicObjectGetFn; 871 1.1 joerg } 872 1.1 joerg 873 1.1 joerg llvm::FunctionCallee GetCppAtomicObjectSetFunction() override { 874 1.1 joerg // The optimised functions were added in version 1.7 of the GNUstep 875 1.1 joerg // runtime. 876 1.1 joerg assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= 877 1.1 joerg VersionTuple(1, 7)); 878 1.1 joerg return CxxAtomicObjectSetFn; 879 1.1 joerg } 880 1.1 joerg 881 1.1 joerg llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, 882 1.1 joerg bool copy) override { 883 1.1 joerg // The optimised property functions omit the GC check, and so are not 884 1.1 joerg // safe to use in GC mode. The standard functions are fast in GC mode, 885 1.1 joerg // so there is less advantage in using them. 886 1.1 joerg assert ((CGM.getLangOpts().getGC() == LangOptions::NonGC)); 887 1.1 joerg // The optimised functions were added in version 1.7 of the GNUstep 888 1.1 joerg // runtime. 889 1.1 joerg assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= 890 1.1 joerg VersionTuple(1, 7)); 891 1.1 joerg 892 1.1 joerg if (atomic) { 893 1.1 joerg if (copy) return SetPropertyAtomicCopy; 894 1.1 joerg return SetPropertyAtomic; 895 1.1 joerg } 896 1.1 joerg 897 1.1 joerg return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic; 898 1.1 joerg } 899 1.1 joerg }; 900 1.1 joerg 901 1.1 joerg /// GNUstep Objective-C ABI version 2 implementation. 902 1.1 joerg /// This is the ABI that provides a clean break with the legacy GCC ABI and 903 1.1 joerg /// cleans up a number of things that were added to work around 1980s linkers. 904 1.1 joerg class CGObjCGNUstep2 : public CGObjCGNUstep { 905 1.1 joerg enum SectionKind 906 1.1 joerg { 907 1.1 joerg SelectorSection = 0, 908 1.1 joerg ClassSection, 909 1.1 joerg ClassReferenceSection, 910 1.1 joerg CategorySection, 911 1.1 joerg ProtocolSection, 912 1.1 joerg ProtocolReferenceSection, 913 1.1 joerg ClassAliasSection, 914 1.1 joerg ConstantStringSection 915 1.1 joerg }; 916 1.1 joerg static const char *const SectionsBaseNames[8]; 917 1.1 joerg static const char *const PECOFFSectionsBaseNames[8]; 918 1.1 joerg template<SectionKind K> 919 1.1 joerg std::string sectionName() { 920 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) { 921 1.1 joerg std::string name(PECOFFSectionsBaseNames[K]); 922 1.1 joerg name += "$m"; 923 1.1 joerg return name; 924 1.1 joerg } 925 1.1 joerg return SectionsBaseNames[K]; 926 1.1 joerg } 927 1.1 joerg /// The GCC ABI superclass message lookup function. Takes a pointer to a 928 1.1 joerg /// structure describing the receiver and the class, and a selector as 929 1.1 joerg /// arguments. Returns the IMP for the corresponding method. 930 1.1 joerg LazyRuntimeFunction MsgLookupSuperFn; 931 1.1 joerg /// A flag indicating if we've emitted at least one protocol. 932 1.1 joerg /// If we haven't, then we need to emit an empty protocol, to ensure that the 933 1.1 joerg /// __start__objc_protocols and __stop__objc_protocols sections exist. 934 1.1 joerg bool EmittedProtocol = false; 935 1.1 joerg /// A flag indicating if we've emitted at least one protocol reference. 936 1.1 joerg /// If we haven't, then we need to emit an empty protocol, to ensure that the 937 1.1 joerg /// __start__objc_protocol_refs and __stop__objc_protocol_refs sections 938 1.1 joerg /// exist. 939 1.1 joerg bool EmittedProtocolRef = false; 940 1.1 joerg /// A flag indicating if we've emitted at least one class. 941 1.1 joerg /// If we haven't, then we need to emit an empty protocol, to ensure that the 942 1.1 joerg /// __start__objc_classes and __stop__objc_classes sections / exist. 943 1.1 joerg bool EmittedClass = false; 944 1.1 joerg /// Generate the name of a symbol for a reference to a class. Accesses to 945 1.1 joerg /// classes should be indirected via this. 946 1.1 joerg 947 1.1 joerg typedef std::pair<std::string, std::pair<llvm::Constant*, int>> EarlyInitPair; 948 1.1 joerg std::vector<EarlyInitPair> EarlyInitList; 949 1.1 joerg 950 1.1 joerg std::string SymbolForClassRef(StringRef Name, bool isWeak) { 951 1.1 joerg if (isWeak) 952 1.1 joerg return (ManglePublicSymbol("OBJC_WEAK_REF_CLASS_") + Name).str(); 953 1.1 joerg else 954 1.1 joerg return (ManglePublicSymbol("OBJC_REF_CLASS_") + Name).str(); 955 1.1 joerg } 956 1.1 joerg /// Generate the name of a class symbol. 957 1.1 joerg std::string SymbolForClass(StringRef Name) { 958 1.1 joerg return (ManglePublicSymbol("OBJC_CLASS_") + Name).str(); 959 1.1 joerg } 960 1.1 joerg void CallRuntimeFunction(CGBuilderTy &B, StringRef FunctionName, 961 1.1 joerg ArrayRef<llvm::Value*> Args) { 962 1.1 joerg SmallVector<llvm::Type *,8> Types; 963 1.1 joerg for (auto *Arg : Args) 964 1.1 joerg Types.push_back(Arg->getType()); 965 1.1 joerg llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types, 966 1.1 joerg false); 967 1.1 joerg llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FT, FunctionName); 968 1.1 joerg B.CreateCall(Fn, Args); 969 1.1 joerg } 970 1.1 joerg 971 1.1 joerg ConstantAddress GenerateConstantString(const StringLiteral *SL) override { 972 1.1 joerg 973 1.1 joerg auto Str = SL->getString(); 974 1.1 joerg CharUnits Align = CGM.getPointerAlign(); 975 1.1 joerg 976 1.1 joerg // Look for an existing one 977 1.1 joerg llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str); 978 1.1 joerg if (old != ObjCStrings.end()) 979 1.1 joerg return ConstantAddress(old->getValue(), Align); 980 1.1 joerg 981 1.1 joerg bool isNonASCII = SL->containsNonAscii(); 982 1.1 joerg 983 1.1 joerg auto LiteralLength = SL->getLength(); 984 1.1 joerg 985 1.1 joerg if ((CGM.getTarget().getPointerWidth(0) == 64) && 986 1.1 joerg (LiteralLength < 9) && !isNonASCII) { 987 1.1 joerg // Tiny strings are only used on 64-bit platforms. They store 8 7-bit 988 1.1 joerg // ASCII characters in the high 56 bits, followed by a 4-bit length and a 989 1.1 joerg // 3-bit tag (which is always 4). 990 1.1 joerg uint64_t str = 0; 991 1.1 joerg // Fill in the characters 992 1.1 joerg for (unsigned i=0 ; i<LiteralLength ; i++) 993 1.1 joerg str |= ((uint64_t)SL->getCodeUnit(i)) << ((64 - 4 - 3) - (i*7)); 994 1.1 joerg // Fill in the length 995 1.1 joerg str |= LiteralLength << 3; 996 1.1 joerg // Set the tag 997 1.1 joerg str |= 4; 998 1.1 joerg auto *ObjCStr = llvm::ConstantExpr::getIntToPtr( 999 1.1 joerg llvm::ConstantInt::get(Int64Ty, str), IdTy); 1000 1.1 joerg ObjCStrings[Str] = ObjCStr; 1001 1.1 joerg return ConstantAddress(ObjCStr, Align); 1002 1.1 joerg } 1003 1.1 joerg 1004 1.1 joerg StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass; 1005 1.1 joerg 1006 1.1 joerg if (StringClass.empty()) StringClass = "NSConstantString"; 1007 1.1 joerg 1008 1.1 joerg std::string Sym = SymbolForClass(StringClass); 1009 1.1 joerg 1010 1.1 joerg llvm::Constant *isa = TheModule.getNamedGlobal(Sym); 1011 1.1 joerg 1012 1.1 joerg if (!isa) { 1013 1.1 joerg isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false, 1014 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, Sym); 1015 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) { 1016 1.1 joerg cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); 1017 1.1 joerg } 1018 1.1 joerg } else if (isa->getType() != PtrToIdTy) 1019 1.1 joerg isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy); 1020 1.1 joerg 1021 1.1 joerg // struct 1022 1.1 joerg // { 1023 1.1 joerg // Class isa; 1024 1.1 joerg // uint32_t flags; 1025 1.1 joerg // uint32_t length; // Number of codepoints 1026 1.1 joerg // uint32_t size; // Number of bytes 1027 1.1 joerg // uint32_t hash; 1028 1.1 joerg // const char *data; 1029 1.1 joerg // }; 1030 1.1 joerg 1031 1.1 joerg ConstantInitBuilder Builder(CGM); 1032 1.1 joerg auto Fields = Builder.beginStruct(); 1033 1.1 joerg if (!CGM.getTriple().isOSBinFormatCOFF()) { 1034 1.1 joerg Fields.add(isa); 1035 1.1 joerg } else { 1036 1.1 joerg Fields.addNullPointer(PtrTy); 1037 1.1 joerg } 1038 1.1 joerg // For now, all non-ASCII strings are represented as UTF-16. As such, the 1039 1.1 joerg // number of bytes is simply double the number of UTF-16 codepoints. In 1040 1.1 joerg // ASCII strings, the number of bytes is equal to the number of non-ASCII 1041 1.1 joerg // codepoints. 1042 1.1 joerg if (isNonASCII) { 1043 1.1 joerg unsigned NumU8CodeUnits = Str.size(); 1044 1.1 joerg // A UTF-16 representation of a unicode string contains at most the same 1045 1.1 joerg // number of code units as a UTF-8 representation. Allocate that much 1046 1.1 joerg // space, plus one for the final null character. 1047 1.1 joerg SmallVector<llvm::UTF16, 128> ToBuf(NumU8CodeUnits + 1); 1048 1.1 joerg const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)Str.data(); 1049 1.1 joerg llvm::UTF16 *ToPtr = &ToBuf[0]; 1050 1.1 joerg (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits, 1051 1.1 joerg &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion); 1052 1.1 joerg uint32_t StringLength = ToPtr - &ToBuf[0]; 1053 1.1 joerg // Add null terminator 1054 1.1 joerg *ToPtr = 0; 1055 1.1 joerg // Flags: 2 indicates UTF-16 encoding 1056 1.1 joerg Fields.addInt(Int32Ty, 2); 1057 1.1 joerg // Number of UTF-16 codepoints 1058 1.1 joerg Fields.addInt(Int32Ty, StringLength); 1059 1.1 joerg // Number of bytes 1060 1.1 joerg Fields.addInt(Int32Ty, StringLength * 2); 1061 1.1 joerg // Hash. Not currently initialised by the compiler. 1062 1.1 joerg Fields.addInt(Int32Ty, 0); 1063 1.1 joerg // pointer to the data string. 1064 1.1 joerg auto Arr = llvm::makeArrayRef(&ToBuf[0], ToPtr+1); 1065 1.1 joerg auto *C = llvm::ConstantDataArray::get(VMContext, Arr); 1066 1.1 joerg auto *Buffer = new llvm::GlobalVariable(TheModule, C->getType(), 1067 1.1 joerg /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, C, ".str"); 1068 1.1 joerg Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); 1069 1.1 joerg Fields.add(Buffer); 1070 1.1 joerg } else { 1071 1.1 joerg // Flags: 0 indicates ASCII encoding 1072 1.1 joerg Fields.addInt(Int32Ty, 0); 1073 1.1 joerg // Number of UTF-16 codepoints, each ASCII byte is a UTF-16 codepoint 1074 1.1 joerg Fields.addInt(Int32Ty, Str.size()); 1075 1.1 joerg // Number of bytes 1076 1.1 joerg Fields.addInt(Int32Ty, Str.size()); 1077 1.1 joerg // Hash. Not currently initialised by the compiler. 1078 1.1 joerg Fields.addInt(Int32Ty, 0); 1079 1.1 joerg // Data pointer 1080 1.1 joerg Fields.add(MakeConstantString(Str)); 1081 1.1 joerg } 1082 1.1 joerg std::string StringName; 1083 1.1 joerg bool isNamed = !isNonASCII; 1084 1.1 joerg if (isNamed) { 1085 1.1 joerg StringName = ".objc_str_"; 1086 1.1 joerg for (int i=0,e=Str.size() ; i<e ; ++i) { 1087 1.1 joerg unsigned char c = Str[i]; 1088 1.1 joerg if (isalnum(c)) 1089 1.1 joerg StringName += c; 1090 1.1 joerg else if (c == ' ') 1091 1.1 joerg StringName += '_'; 1092 1.1 joerg else { 1093 1.1 joerg isNamed = false; 1094 1.1 joerg break; 1095 1.1 joerg } 1096 1.1 joerg } 1097 1.1 joerg } 1098 1.1 joerg auto *ObjCStrGV = 1099 1.1 joerg Fields.finishAndCreateGlobal( 1100 1.1 joerg isNamed ? StringRef(StringName) : ".objc_string", 1101 1.1 joerg Align, false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage 1102 1.1 joerg : llvm::GlobalValue::PrivateLinkage); 1103 1.1 joerg ObjCStrGV->setSection(sectionName<ConstantStringSection>()); 1104 1.1 joerg if (isNamed) { 1105 1.1 joerg ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName)); 1106 1.1 joerg ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 1107 1.1 joerg } 1108 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) { 1109 1.1 joerg std::pair<llvm::Constant*, int> v{ObjCStrGV, 0}; 1110 1.1 joerg EarlyInitList.emplace_back(Sym, v); 1111 1.1 joerg } 1112 1.1 joerg llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy); 1113 1.1 joerg ObjCStrings[Str] = ObjCStr; 1114 1.1 joerg ConstantStrings.push_back(ObjCStr); 1115 1.1 joerg return ConstantAddress(ObjCStr, Align); 1116 1.1 joerg } 1117 1.1 joerg 1118 1.1 joerg void PushProperty(ConstantArrayBuilder &PropertiesArray, 1119 1.1 joerg const ObjCPropertyDecl *property, 1120 1.1 joerg const Decl *OCD, 1121 1.1 joerg bool isSynthesized=true, bool 1122 1.1 joerg isDynamic=true) override { 1123 1.1 joerg // struct objc_property 1124 1.1 joerg // { 1125 1.1 joerg // const char *name; 1126 1.1 joerg // const char *attributes; 1127 1.1 joerg // const char *type; 1128 1.1 joerg // SEL getter; 1129 1.1 joerg // SEL setter; 1130 1.1 joerg // }; 1131 1.1 joerg auto Fields = PropertiesArray.beginStruct(PropertyMetadataTy); 1132 1.1 joerg ASTContext &Context = CGM.getContext(); 1133 1.1 joerg Fields.add(MakeConstantString(property->getNameAsString())); 1134 1.1 joerg std::string TypeStr = 1135 1.1 joerg CGM.getContext().getObjCEncodingForPropertyDecl(property, OCD); 1136 1.1 joerg Fields.add(MakeConstantString(TypeStr)); 1137 1.1 joerg std::string typeStr; 1138 1.1 joerg Context.getObjCEncodingForType(property->getType(), typeStr); 1139 1.1 joerg Fields.add(MakeConstantString(typeStr)); 1140 1.1 joerg auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) { 1141 1.1 joerg if (accessor) { 1142 1.1 joerg std::string TypeStr = Context.getObjCEncodingForMethodDecl(accessor); 1143 1.1 joerg Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr)); 1144 1.1 joerg } else { 1145 1.1 joerg Fields.add(NULLPtr); 1146 1.1 joerg } 1147 1.1 joerg }; 1148 1.1 joerg addPropertyMethod(property->getGetterMethodDecl()); 1149 1.1 joerg addPropertyMethod(property->getSetterMethodDecl()); 1150 1.1 joerg Fields.finishAndAddTo(PropertiesArray); 1151 1.1 joerg } 1152 1.1 joerg 1153 1.1 joerg llvm::Constant * 1154 1.1 joerg GenerateProtocolMethodList(ArrayRef<const ObjCMethodDecl*> Methods) override { 1155 1.1 joerg // struct objc_protocol_method_description 1156 1.1 joerg // { 1157 1.1 joerg // SEL selector; 1158 1.1 joerg // const char *types; 1159 1.1 joerg // }; 1160 1.1 joerg llvm::StructType *ObjCMethodDescTy = 1161 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), 1162 1.1 joerg { PtrToInt8Ty, PtrToInt8Ty }); 1163 1.1 joerg ASTContext &Context = CGM.getContext(); 1164 1.1 joerg ConstantInitBuilder Builder(CGM); 1165 1.1 joerg // struct objc_protocol_method_description_list 1166 1.1 joerg // { 1167 1.1 joerg // int count; 1168 1.1 joerg // int size; 1169 1.1 joerg // struct objc_protocol_method_description methods[]; 1170 1.1 joerg // }; 1171 1.1 joerg auto MethodList = Builder.beginStruct(); 1172 1.1 joerg // int count; 1173 1.1 joerg MethodList.addInt(IntTy, Methods.size()); 1174 1.1 joerg // int size; // sizeof(struct objc_method_description) 1175 1.1 joerg llvm::DataLayout td(&TheModule); 1176 1.1 joerg MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) / 1177 1.1 joerg CGM.getContext().getCharWidth()); 1178 1.1 joerg // struct objc_method_description[] 1179 1.1 joerg auto MethodArray = MethodList.beginArray(ObjCMethodDescTy); 1180 1.1 joerg for (auto *M : Methods) { 1181 1.1 joerg auto Method = MethodArray.beginStruct(ObjCMethodDescTy); 1182 1.1 joerg Method.add(CGObjCGNU::GetConstantSelector(M)); 1183 1.1 joerg Method.add(GetTypeString(Context.getObjCEncodingForMethodDecl(M, true))); 1184 1.1 joerg Method.finishAndAddTo(MethodArray); 1185 1.1 joerg } 1186 1.1 joerg MethodArray.finishAndAddTo(MethodList); 1187 1.1 joerg return MethodList.finishAndCreateGlobal(".objc_protocol_method_list", 1188 1.1 joerg CGM.getPointerAlign()); 1189 1.1 joerg } 1190 1.1 joerg llvm::Constant *GenerateCategoryProtocolList(const ObjCCategoryDecl *OCD) 1191 1.1 joerg override { 1192 1.1.1.2 joerg const auto &ReferencedProtocols = OCD->getReferencedProtocols(); 1193 1.1.1.2 joerg auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(), 1194 1.1.1.2 joerg ReferencedProtocols.end()); 1195 1.1.1.2 joerg SmallVector<llvm::Constant *, 16> Protocols; 1196 1.1.1.2 joerg for (const auto *PI : RuntimeProtocols) 1197 1.1 joerg Protocols.push_back( 1198 1.1 joerg llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI), 1199 1.1 joerg ProtocolPtrTy)); 1200 1.1 joerg return GenerateProtocolList(Protocols); 1201 1.1 joerg } 1202 1.1 joerg 1203 1.1 joerg llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, 1204 1.1 joerg llvm::Value *cmd, MessageSendInfo &MSI) override { 1205 1.1 joerg // Don't access the slot unless we're trying to cache the result. 1206 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 1207 1.1 joerg llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, ObjCSuper, 1208 1.1 joerg PtrToObjCSuperTy).getPointer(), cmd}; 1209 1.1 joerg return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); 1210 1.1 joerg } 1211 1.1 joerg 1212 1.1 joerg llvm::GlobalVariable *GetClassVar(StringRef Name, bool isWeak=false) { 1213 1.1 joerg std::string SymbolName = SymbolForClassRef(Name, isWeak); 1214 1.1 joerg auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName); 1215 1.1 joerg if (ClassSymbol) 1216 1.1 joerg return ClassSymbol; 1217 1.1 joerg ClassSymbol = new llvm::GlobalVariable(TheModule, 1218 1.1 joerg IdTy, false, llvm::GlobalValue::ExternalLinkage, 1219 1.1 joerg nullptr, SymbolName); 1220 1.1 joerg // If this is a weak symbol, then we are creating a valid definition for 1221 1.1 joerg // the symbol, pointing to a weak definition of the real class pointer. If 1222 1.1 joerg // this is not a weak reference, then we are expecting another compilation 1223 1.1 joerg // unit to provide the real indirection symbol. 1224 1.1 joerg if (isWeak) 1225 1.1 joerg ClassSymbol->setInitializer(new llvm::GlobalVariable(TheModule, 1226 1.1 joerg Int8Ty, false, llvm::GlobalValue::ExternalWeakLinkage, 1227 1.1 joerg nullptr, SymbolForClass(Name))); 1228 1.1 joerg else { 1229 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) { 1230 1.1 joerg IdentifierInfo &II = CGM.getContext().Idents.get(Name); 1231 1.1 joerg TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 1232 1.1 joerg DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 1233 1.1 joerg 1234 1.1 joerg const ObjCInterfaceDecl *OID = nullptr; 1235 1.1.1.2 joerg for (const auto *Result : DC->lookup(&II)) 1236 1.1 joerg if ((OID = dyn_cast<ObjCInterfaceDecl>(Result))) 1237 1.1 joerg break; 1238 1.1 joerg 1239 1.1 joerg // The first Interface we find may be a @class, 1240 1.1 joerg // which should only be treated as the source of 1241 1.1 joerg // truth in the absence of a true declaration. 1242 1.1.1.2 joerg assert(OID && "Failed to find ObjCInterfaceDecl"); 1243 1.1 joerg const ObjCInterfaceDecl *OIDDef = OID->getDefinition(); 1244 1.1 joerg if (OIDDef != nullptr) 1245 1.1 joerg OID = OIDDef; 1246 1.1 joerg 1247 1.1 joerg auto Storage = llvm::GlobalValue::DefaultStorageClass; 1248 1.1 joerg if (OID->hasAttr<DLLImportAttr>()) 1249 1.1 joerg Storage = llvm::GlobalValue::DLLImportStorageClass; 1250 1.1 joerg else if (OID->hasAttr<DLLExportAttr>()) 1251 1.1 joerg Storage = llvm::GlobalValue::DLLExportStorageClass; 1252 1.1 joerg 1253 1.1 joerg cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage); 1254 1.1 joerg } 1255 1.1 joerg } 1256 1.1 joerg assert(ClassSymbol->getName() == SymbolName); 1257 1.1 joerg return ClassSymbol; 1258 1.1 joerg } 1259 1.1 joerg llvm::Value *GetClassNamed(CodeGenFunction &CGF, 1260 1.1 joerg const std::string &Name, 1261 1.1 joerg bool isWeak) override { 1262 1.1 joerg return CGF.Builder.CreateLoad(Address(GetClassVar(Name, isWeak), 1263 1.1 joerg CGM.getPointerAlign())); 1264 1.1 joerg } 1265 1.1 joerg int32_t FlagsForOwnership(Qualifiers::ObjCLifetime Ownership) { 1266 1.1 joerg // typedef enum { 1267 1.1 joerg // ownership_invalid = 0, 1268 1.1 joerg // ownership_strong = 1, 1269 1.1 joerg // ownership_weak = 2, 1270 1.1 joerg // ownership_unsafe = 3 1271 1.1 joerg // } ivar_ownership; 1272 1.1 joerg int Flag; 1273 1.1 joerg switch (Ownership) { 1274 1.1 joerg case Qualifiers::OCL_Strong: 1275 1.1 joerg Flag = 1; 1276 1.1 joerg break; 1277 1.1 joerg case Qualifiers::OCL_Weak: 1278 1.1 joerg Flag = 2; 1279 1.1 joerg break; 1280 1.1 joerg case Qualifiers::OCL_ExplicitNone: 1281 1.1 joerg Flag = 3; 1282 1.1 joerg break; 1283 1.1 joerg case Qualifiers::OCL_None: 1284 1.1 joerg case Qualifiers::OCL_Autoreleasing: 1285 1.1 joerg assert(Ownership != Qualifiers::OCL_Autoreleasing); 1286 1.1 joerg Flag = 0; 1287 1.1 joerg } 1288 1.1 joerg return Flag; 1289 1.1 joerg } 1290 1.1 joerg llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames, 1291 1.1 joerg ArrayRef<llvm::Constant *> IvarTypes, 1292 1.1 joerg ArrayRef<llvm::Constant *> IvarOffsets, 1293 1.1 joerg ArrayRef<llvm::Constant *> IvarAlign, 1294 1.1 joerg ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership) override { 1295 1.1 joerg llvm_unreachable("Method should not be called!"); 1296 1.1 joerg } 1297 1.1 joerg 1298 1.1 joerg llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName) override { 1299 1.1 joerg std::string Name = SymbolForProtocol(ProtocolName); 1300 1.1 joerg auto *GV = TheModule.getGlobalVariable(Name); 1301 1.1 joerg if (!GV) { 1302 1.1 joerg // Emit a placeholder symbol. 1303 1.1 joerg GV = new llvm::GlobalVariable(TheModule, ProtocolTy, false, 1304 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, Name); 1305 1.1 joerg GV->setAlignment(CGM.getPointerAlign().getAsAlign()); 1306 1.1 joerg } 1307 1.1 joerg return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy); 1308 1.1 joerg } 1309 1.1 joerg 1310 1.1 joerg /// Existing protocol references. 1311 1.1 joerg llvm::StringMap<llvm::Constant*> ExistingProtocolRefs; 1312 1.1 joerg 1313 1.1 joerg llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, 1314 1.1 joerg const ObjCProtocolDecl *PD) override { 1315 1.1 joerg auto Name = PD->getNameAsString(); 1316 1.1 joerg auto *&Ref = ExistingProtocolRefs[Name]; 1317 1.1 joerg if (!Ref) { 1318 1.1 joerg auto *&Protocol = ExistingProtocols[Name]; 1319 1.1 joerg if (!Protocol) 1320 1.1 joerg Protocol = GenerateProtocolRef(PD); 1321 1.1 joerg std::string RefName = SymbolForProtocolRef(Name); 1322 1.1 joerg assert(!TheModule.getGlobalVariable(RefName)); 1323 1.1 joerg // Emit a reference symbol. 1324 1.1 joerg auto GV = new llvm::GlobalVariable(TheModule, ProtocolPtrTy, 1325 1.1 joerg false, llvm::GlobalValue::LinkOnceODRLinkage, 1326 1.1 joerg llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName); 1327 1.1 joerg GV->setComdat(TheModule.getOrInsertComdat(RefName)); 1328 1.1 joerg GV->setSection(sectionName<ProtocolReferenceSection>()); 1329 1.1 joerg GV->setAlignment(CGM.getPointerAlign().getAsAlign()); 1330 1.1 joerg Ref = GV; 1331 1.1 joerg } 1332 1.1 joerg EmittedProtocolRef = true; 1333 1.1.1.2 joerg return CGF.Builder.CreateAlignedLoad(ProtocolPtrTy, Ref, 1334 1.1.1.2 joerg CGM.getPointerAlign()); 1335 1.1 joerg } 1336 1.1 joerg 1337 1.1 joerg llvm::Constant *GenerateProtocolList(ArrayRef<llvm::Constant*> Protocols) { 1338 1.1 joerg llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy, 1339 1.1 joerg Protocols.size()); 1340 1.1 joerg llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 1341 1.1 joerg Protocols); 1342 1.1 joerg ConstantInitBuilder builder(CGM); 1343 1.1 joerg auto ProtocolBuilder = builder.beginStruct(); 1344 1.1 joerg ProtocolBuilder.addNullPointer(PtrTy); 1345 1.1 joerg ProtocolBuilder.addInt(SizeTy, Protocols.size()); 1346 1.1 joerg ProtocolBuilder.add(ProtocolArray); 1347 1.1 joerg return ProtocolBuilder.finishAndCreateGlobal(".objc_protocol_list", 1348 1.1 joerg CGM.getPointerAlign(), false, llvm::GlobalValue::InternalLinkage); 1349 1.1 joerg } 1350 1.1 joerg 1351 1.1 joerg void GenerateProtocol(const ObjCProtocolDecl *PD) override { 1352 1.1 joerg // Do nothing - we only emit referenced protocols. 1353 1.1 joerg } 1354 1.1.1.2 joerg llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) override { 1355 1.1 joerg std::string ProtocolName = PD->getNameAsString(); 1356 1.1 joerg auto *&Protocol = ExistingProtocols[ProtocolName]; 1357 1.1 joerg if (Protocol) 1358 1.1 joerg return Protocol; 1359 1.1 joerg 1360 1.1 joerg EmittedProtocol = true; 1361 1.1 joerg 1362 1.1 joerg auto SymName = SymbolForProtocol(ProtocolName); 1363 1.1 joerg auto *OldGV = TheModule.getGlobalVariable(SymName); 1364 1.1 joerg 1365 1.1 joerg // Use the protocol definition, if there is one. 1366 1.1 joerg if (const ObjCProtocolDecl *Def = PD->getDefinition()) 1367 1.1 joerg PD = Def; 1368 1.1 joerg else { 1369 1.1 joerg // If there is no definition, then create an external linkage symbol and 1370 1.1 joerg // hope that someone else fills it in for us (and fail to link if they 1371 1.1 joerg // don't). 1372 1.1 joerg assert(!OldGV); 1373 1.1 joerg Protocol = new llvm::GlobalVariable(TheModule, ProtocolTy, 1374 1.1 joerg /*isConstant*/false, 1375 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, SymName); 1376 1.1 joerg return Protocol; 1377 1.1 joerg } 1378 1.1 joerg 1379 1.1 joerg SmallVector<llvm::Constant*, 16> Protocols; 1380 1.1.1.2 joerg auto RuntimeProtocols = 1381 1.1.1.2 joerg GetRuntimeProtocolList(PD->protocol_begin(), PD->protocol_end()); 1382 1.1.1.2 joerg for (const auto *PI : RuntimeProtocols) 1383 1.1 joerg Protocols.push_back( 1384 1.1 joerg llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI), 1385 1.1 joerg ProtocolPtrTy)); 1386 1.1 joerg llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); 1387 1.1 joerg 1388 1.1 joerg // Collect information about methods 1389 1.1 joerg llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList; 1390 1.1 joerg llvm::Constant *ClassMethodList, *OptionalClassMethodList; 1391 1.1 joerg EmitProtocolMethodList(PD->instance_methods(), InstanceMethodList, 1392 1.1 joerg OptionalInstanceMethodList); 1393 1.1 joerg EmitProtocolMethodList(PD->class_methods(), ClassMethodList, 1394 1.1 joerg OptionalClassMethodList); 1395 1.1 joerg 1396 1.1 joerg // The isa pointer must be set to a magic number so the runtime knows it's 1397 1.1 joerg // the correct layout. 1398 1.1 joerg ConstantInitBuilder builder(CGM); 1399 1.1 joerg auto ProtocolBuilder = builder.beginStruct(); 1400 1.1 joerg ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr( 1401 1.1 joerg llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy)); 1402 1.1 joerg ProtocolBuilder.add(MakeConstantString(ProtocolName)); 1403 1.1 joerg ProtocolBuilder.add(ProtocolList); 1404 1.1 joerg ProtocolBuilder.add(InstanceMethodList); 1405 1.1 joerg ProtocolBuilder.add(ClassMethodList); 1406 1.1 joerg ProtocolBuilder.add(OptionalInstanceMethodList); 1407 1.1 joerg ProtocolBuilder.add(OptionalClassMethodList); 1408 1.1 joerg // Required instance properties 1409 1.1 joerg ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, false, false)); 1410 1.1 joerg // Optional instance properties 1411 1.1 joerg ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, false, true)); 1412 1.1 joerg // Required class properties 1413 1.1 joerg ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, true, false)); 1414 1.1 joerg // Optional class properties 1415 1.1 joerg ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, true, true)); 1416 1.1 joerg 1417 1.1 joerg auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName, 1418 1.1 joerg CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage); 1419 1.1 joerg GV->setSection(sectionName<ProtocolSection>()); 1420 1.1 joerg GV->setComdat(TheModule.getOrInsertComdat(SymName)); 1421 1.1 joerg if (OldGV) { 1422 1.1 joerg OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV, 1423 1.1 joerg OldGV->getType())); 1424 1.1 joerg OldGV->removeFromParent(); 1425 1.1 joerg GV->setName(SymName); 1426 1.1 joerg } 1427 1.1 joerg Protocol = GV; 1428 1.1 joerg return GV; 1429 1.1 joerg } 1430 1.1 joerg llvm::Constant *EnforceType(llvm::Constant *Val, llvm::Type *Ty) { 1431 1.1 joerg if (Val->getType() == Ty) 1432 1.1 joerg return Val; 1433 1.1 joerg return llvm::ConstantExpr::getBitCast(Val, Ty); 1434 1.1 joerg } 1435 1.1 joerg llvm::Value *GetTypedSelector(CodeGenFunction &CGF, Selector Sel, 1436 1.1 joerg const std::string &TypeEncoding) override { 1437 1.1 joerg return GetConstantSelector(Sel, TypeEncoding); 1438 1.1 joerg } 1439 1.1 joerg llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) { 1440 1.1 joerg if (TypeEncoding.empty()) 1441 1.1 joerg return NULLPtr; 1442 1.1.1.2 joerg std::string MangledTypes = std::string(TypeEncoding); 1443 1.1 joerg std::replace(MangledTypes.begin(), MangledTypes.end(), 1444 1.1 joerg '@', '\1'); 1445 1.1 joerg std::string TypesVarName = ".objc_sel_types_" + MangledTypes; 1446 1.1 joerg auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName); 1447 1.1 joerg if (!TypesGlobal) { 1448 1.1 joerg llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext, 1449 1.1 joerg TypeEncoding); 1450 1.1 joerg auto *GV = new llvm::GlobalVariable(TheModule, Init->getType(), 1451 1.1 joerg true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName); 1452 1.1 joerg GV->setComdat(TheModule.getOrInsertComdat(TypesVarName)); 1453 1.1 joerg GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 1454 1.1 joerg TypesGlobal = GV; 1455 1.1 joerg } 1456 1.1 joerg return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(), 1457 1.1 joerg TypesGlobal, Zeros); 1458 1.1 joerg } 1459 1.1 joerg llvm::Constant *GetConstantSelector(Selector Sel, 1460 1.1 joerg const std::string &TypeEncoding) override { 1461 1.1 joerg // @ is used as a special character in symbol names (used for symbol 1462 1.1 joerg // versioning), so mangle the name to not include it. Replace it with a 1463 1.1 joerg // character that is not a valid type encoding character (and, being 1464 1.1 joerg // non-printable, never will be!) 1465 1.1 joerg std::string MangledTypes = TypeEncoding; 1466 1.1 joerg std::replace(MangledTypes.begin(), MangledTypes.end(), 1467 1.1 joerg '@', '\1'); 1468 1.1 joerg auto SelVarName = (StringRef(".objc_selector_") + Sel.getAsString() + "_" + 1469 1.1 joerg MangledTypes).str(); 1470 1.1 joerg if (auto *GV = TheModule.getNamedGlobal(SelVarName)) 1471 1.1 joerg return EnforceType(GV, SelectorTy); 1472 1.1 joerg ConstantInitBuilder builder(CGM); 1473 1.1 joerg auto SelBuilder = builder.beginStruct(); 1474 1.1 joerg SelBuilder.add(ExportUniqueString(Sel.getAsString(), ".objc_sel_name_", 1475 1.1 joerg true)); 1476 1.1 joerg SelBuilder.add(GetTypeString(TypeEncoding)); 1477 1.1 joerg auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName, 1478 1.1 joerg CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage); 1479 1.1 joerg GV->setComdat(TheModule.getOrInsertComdat(SelVarName)); 1480 1.1 joerg GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 1481 1.1 joerg GV->setSection(sectionName<SelectorSection>()); 1482 1.1 joerg auto *SelVal = EnforceType(GV, SelectorTy); 1483 1.1 joerg return SelVal; 1484 1.1 joerg } 1485 1.1 joerg llvm::StructType *emptyStruct = nullptr; 1486 1.1 joerg 1487 1.1 joerg /// Return pointers to the start and end of a section. On ELF platforms, we 1488 1.1 joerg /// use the __start_ and __stop_ symbols that GNU-compatible linkers will set 1489 1.1 joerg /// to the start and end of section names, as long as those section names are 1490 1.1 joerg /// valid identifiers and the symbols are referenced but not defined. On 1491 1.1 joerg /// Windows, we use the fact that MSVC-compatible linkers will lexically sort 1492 1.1 joerg /// by subsections and place everything that we want to reference in a middle 1493 1.1 joerg /// subsection and then insert zero-sized symbols in subsections a and z. 1494 1.1 joerg std::pair<llvm::Constant*,llvm::Constant*> 1495 1.1 joerg GetSectionBounds(StringRef Section) { 1496 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) { 1497 1.1 joerg if (emptyStruct == nullptr) { 1498 1.1 joerg emptyStruct = llvm::StructType::create(VMContext, ".objc_section_sentinel"); 1499 1.1 joerg emptyStruct->setBody({}, /*isPacked*/true); 1500 1.1 joerg } 1501 1.1 joerg auto ZeroInit = llvm::Constant::getNullValue(emptyStruct); 1502 1.1 joerg auto Sym = [&](StringRef Prefix, StringRef SecSuffix) { 1503 1.1 joerg auto *Sym = new llvm::GlobalVariable(TheModule, emptyStruct, 1504 1.1 joerg /*isConstant*/false, 1505 1.1 joerg llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix + 1506 1.1 joerg Section); 1507 1.1 joerg Sym->setVisibility(llvm::GlobalValue::HiddenVisibility); 1508 1.1 joerg Sym->setSection((Section + SecSuffix).str()); 1509 1.1 joerg Sym->setComdat(TheModule.getOrInsertComdat((Prefix + 1510 1.1 joerg Section).str())); 1511 1.1 joerg Sym->setAlignment(CGM.getPointerAlign().getAsAlign()); 1512 1.1 joerg return Sym; 1513 1.1 joerg }; 1514 1.1 joerg return { Sym("__start_", "$a"), Sym("__stop", "$z") }; 1515 1.1 joerg } 1516 1.1 joerg auto *Start = new llvm::GlobalVariable(TheModule, PtrTy, 1517 1.1 joerg /*isConstant*/false, 1518 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__start_") + 1519 1.1 joerg Section); 1520 1.1 joerg Start->setVisibility(llvm::GlobalValue::HiddenVisibility); 1521 1.1 joerg auto *Stop = new llvm::GlobalVariable(TheModule, PtrTy, 1522 1.1 joerg /*isConstant*/false, 1523 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__stop_") + 1524 1.1 joerg Section); 1525 1.1 joerg Stop->setVisibility(llvm::GlobalValue::HiddenVisibility); 1526 1.1 joerg return { Start, Stop }; 1527 1.1 joerg } 1528 1.1 joerg CatchTypeInfo getCatchAllTypeInfo() override { 1529 1.1 joerg return CGM.getCXXABI().getCatchAllTypeInfo(); 1530 1.1 joerg } 1531 1.1 joerg llvm::Function *ModuleInitFunction() override { 1532 1.1 joerg llvm::Function *LoadFunction = llvm::Function::Create( 1533 1.1 joerg llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false), 1534 1.1 joerg llvm::GlobalValue::LinkOnceODRLinkage, ".objcv2_load_function", 1535 1.1 joerg &TheModule); 1536 1.1 joerg LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility); 1537 1.1 joerg LoadFunction->setComdat(TheModule.getOrInsertComdat(".objcv2_load_function")); 1538 1.1 joerg 1539 1.1 joerg llvm::BasicBlock *EntryBB = 1540 1.1 joerg llvm::BasicBlock::Create(VMContext, "entry", LoadFunction); 1541 1.1 joerg CGBuilderTy B(CGM, VMContext); 1542 1.1 joerg B.SetInsertPoint(EntryBB); 1543 1.1 joerg ConstantInitBuilder builder(CGM); 1544 1.1 joerg auto InitStructBuilder = builder.beginStruct(); 1545 1.1 joerg InitStructBuilder.addInt(Int64Ty, 0); 1546 1.1 joerg auto §ionVec = CGM.getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames; 1547 1.1 joerg for (auto *s : sectionVec) { 1548 1.1 joerg auto bounds = GetSectionBounds(s); 1549 1.1 joerg InitStructBuilder.add(bounds.first); 1550 1.1 joerg InitStructBuilder.add(bounds.second); 1551 1.1 joerg } 1552 1.1 joerg auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init", 1553 1.1 joerg CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage); 1554 1.1 joerg InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility); 1555 1.1 joerg InitStruct->setComdat(TheModule.getOrInsertComdat(".objc_init")); 1556 1.1 joerg 1557 1.1 joerg CallRuntimeFunction(B, "__objc_load", {InitStruct});; 1558 1.1 joerg B.CreateRetVoid(); 1559 1.1 joerg // Make sure that the optimisers don't delete this function. 1560 1.1 joerg CGM.addCompilerUsedGlobal(LoadFunction); 1561 1.1 joerg // FIXME: Currently ELF only! 1562 1.1 joerg // We have to do this by hand, rather than with @llvm.ctors, so that the 1563 1.1 joerg // linker can remove the duplicate invocations. 1564 1.1 joerg auto *InitVar = new llvm::GlobalVariable(TheModule, LoadFunction->getType(), 1565 1.1.1.2 joerg /*isConstant*/false, llvm::GlobalValue::LinkOnceAnyLinkage, 1566 1.1 joerg LoadFunction, ".objc_ctor"); 1567 1.1 joerg // Check that this hasn't been renamed. This shouldn't happen, because 1568 1.1 joerg // this function should be called precisely once. 1569 1.1 joerg assert(InitVar->getName() == ".objc_ctor"); 1570 1.1 joerg // In Windows, initialisers are sorted by the suffix. XCL is for library 1571 1.1 joerg // initialisers, which run before user initialisers. We are running 1572 1.1 joerg // Objective-C loads at the end of library load. This means +load methods 1573 1.1 joerg // will run before any other static constructors, but that static 1574 1.1 joerg // constructors can see a fully initialised Objective-C state. 1575 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) 1576 1.1 joerg InitVar->setSection(".CRT$XCLz"); 1577 1.1 joerg else 1578 1.1 joerg { 1579 1.1 joerg if (CGM.getCodeGenOpts().UseInitArray) 1580 1.1 joerg InitVar->setSection(".init_array"); 1581 1.1 joerg else 1582 1.1 joerg InitVar->setSection(".ctors"); 1583 1.1 joerg } 1584 1.1 joerg InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility); 1585 1.1 joerg InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor")); 1586 1.1 joerg CGM.addUsedGlobal(InitVar); 1587 1.1 joerg for (auto *C : Categories) { 1588 1.1 joerg auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts()); 1589 1.1 joerg Cat->setSection(sectionName<CategorySection>()); 1590 1.1 joerg CGM.addUsedGlobal(Cat); 1591 1.1 joerg } 1592 1.1 joerg auto createNullGlobal = [&](StringRef Name, ArrayRef<llvm::Constant*> Init, 1593 1.1 joerg StringRef Section) { 1594 1.1 joerg auto nullBuilder = builder.beginStruct(); 1595 1.1 joerg for (auto *F : Init) 1596 1.1 joerg nullBuilder.add(F); 1597 1.1 joerg auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.getPointerAlign(), 1598 1.1 joerg false, llvm::GlobalValue::LinkOnceODRLinkage); 1599 1.1 joerg GV->setSection(Section); 1600 1.1 joerg GV->setComdat(TheModule.getOrInsertComdat(Name)); 1601 1.1 joerg GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 1602 1.1 joerg CGM.addUsedGlobal(GV); 1603 1.1 joerg return GV; 1604 1.1 joerg }; 1605 1.1 joerg for (auto clsAlias : ClassAliases) 1606 1.1 joerg createNullGlobal(std::string(".objc_class_alias") + 1607 1.1 joerg clsAlias.second, { MakeConstantString(clsAlias.second), 1608 1.1 joerg GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>()); 1609 1.1 joerg // On ELF platforms, add a null value for each special section so that we 1610 1.1 joerg // can always guarantee that the _start and _stop symbols will exist and be 1611 1.1 joerg // meaningful. This is not required on COFF platforms, where our start and 1612 1.1 joerg // stop symbols will create the section. 1613 1.1 joerg if (!CGM.getTriple().isOSBinFormatCOFF()) { 1614 1.1 joerg createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr}, 1615 1.1 joerg sectionName<SelectorSection>()); 1616 1.1 joerg if (Categories.empty()) 1617 1.1 joerg createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr, 1618 1.1 joerg NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr}, 1619 1.1 joerg sectionName<CategorySection>()); 1620 1.1 joerg if (!EmittedClass) { 1621 1.1 joerg createNullGlobal(".objc_null_cls_init_ref", NULLPtr, 1622 1.1 joerg sectionName<ClassSection>()); 1623 1.1 joerg createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr }, 1624 1.1 joerg sectionName<ClassReferenceSection>()); 1625 1.1 joerg } 1626 1.1 joerg if (!EmittedProtocol) 1627 1.1 joerg createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr, 1628 1.1 joerg NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, 1629 1.1 joerg NULLPtr}, sectionName<ProtocolSection>()); 1630 1.1 joerg if (!EmittedProtocolRef) 1631 1.1 joerg createNullGlobal(".objc_null_protocol_ref", {NULLPtr}, 1632 1.1 joerg sectionName<ProtocolReferenceSection>()); 1633 1.1 joerg if (ClassAliases.empty()) 1634 1.1 joerg createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr }, 1635 1.1 joerg sectionName<ClassAliasSection>()); 1636 1.1 joerg if (ConstantStrings.empty()) { 1637 1.1 joerg auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0); 1638 1.1 joerg createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero, 1639 1.1 joerg i32Zero, i32Zero, i32Zero, NULLPtr }, 1640 1.1 joerg sectionName<ConstantStringSection>()); 1641 1.1 joerg } 1642 1.1 joerg } 1643 1.1 joerg ConstantStrings.clear(); 1644 1.1 joerg Categories.clear(); 1645 1.1 joerg Classes.clear(); 1646 1.1 joerg 1647 1.1 joerg if (EarlyInitList.size() > 0) { 1648 1.1 joerg auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy, 1649 1.1 joerg {}), llvm::GlobalValue::InternalLinkage, ".objc_early_init", 1650 1.1 joerg &CGM.getModule()); 1651 1.1 joerg llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry", 1652 1.1 joerg Init)); 1653 1.1 joerg for (const auto &lateInit : EarlyInitList) { 1654 1.1 joerg auto *global = TheModule.getGlobalVariable(lateInit.first); 1655 1.1 joerg if (global) { 1656 1.1.1.2 joerg b.CreateAlignedStore( 1657 1.1.1.2 joerg global, 1658 1.1.1.2 joerg b.CreateStructGEP(lateInit.second.first, lateInit.second.second), 1659 1.1.1.2 joerg CGM.getPointerAlign().getAsAlign()); 1660 1.1 joerg } 1661 1.1 joerg } 1662 1.1 joerg b.CreateRetVoid(); 1663 1.1 joerg // We can't use the normal LLVM global initialisation array, because we 1664 1.1 joerg // need to specify that this runs early in library initialisation. 1665 1.1.1.2 joerg auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 1666 1.1 joerg /*isConstant*/true, llvm::GlobalValue::InternalLinkage, 1667 1.1 joerg Init, ".objc_early_init_ptr"); 1668 1.1 joerg InitVar->setSection(".CRT$XCLb"); 1669 1.1 joerg CGM.addUsedGlobal(InitVar); 1670 1.1 joerg } 1671 1.1 joerg return nullptr; 1672 1.1 joerg } 1673 1.1 joerg /// In the v2 ABI, ivar offset variables use the type encoding in their name 1674 1.1 joerg /// to trigger linker failures if the types don't match. 1675 1.1 joerg std::string GetIVarOffsetVariableName(const ObjCInterfaceDecl *ID, 1676 1.1 joerg const ObjCIvarDecl *Ivar) override { 1677 1.1 joerg std::string TypeEncoding; 1678 1.1 joerg CGM.getContext().getObjCEncodingForType(Ivar->getType(), TypeEncoding); 1679 1.1 joerg // Prevent the @ from being interpreted as a symbol version. 1680 1.1 joerg std::replace(TypeEncoding.begin(), TypeEncoding.end(), 1681 1.1 joerg '@', '\1'); 1682 1.1 joerg const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() 1683 1.1 joerg + '.' + Ivar->getNameAsString() + '.' + TypeEncoding; 1684 1.1 joerg return Name; 1685 1.1 joerg } 1686 1.1 joerg llvm::Value *EmitIvarOffset(CodeGenFunction &CGF, 1687 1.1 joerg const ObjCInterfaceDecl *Interface, 1688 1.1 joerg const ObjCIvarDecl *Ivar) override { 1689 1.1 joerg const std::string Name = GetIVarOffsetVariableName(Ivar->getContainingInterface(), Ivar); 1690 1.1 joerg llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); 1691 1.1 joerg if (!IvarOffsetPointer) 1692 1.1 joerg IvarOffsetPointer = new llvm::GlobalVariable(TheModule, IntTy, false, 1693 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, Name); 1694 1.1 joerg CharUnits Align = CGM.getIntAlign(); 1695 1.1.1.2 joerg llvm::Value *Offset = 1696 1.1.1.2 joerg CGF.Builder.CreateAlignedLoad(IntTy, IvarOffsetPointer, Align); 1697 1.1 joerg if (Offset->getType() != PtrDiffTy) 1698 1.1 joerg Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); 1699 1.1 joerg return Offset; 1700 1.1 joerg } 1701 1.1 joerg void GenerateClass(const ObjCImplementationDecl *OID) override { 1702 1.1 joerg ASTContext &Context = CGM.getContext(); 1703 1.1 joerg bool IsCOFF = CGM.getTriple().isOSBinFormatCOFF(); 1704 1.1 joerg 1705 1.1 joerg // Get the class name 1706 1.1 joerg ObjCInterfaceDecl *classDecl = 1707 1.1 joerg const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); 1708 1.1 joerg std::string className = classDecl->getNameAsString(); 1709 1.1 joerg auto *classNameConstant = MakeConstantString(className); 1710 1.1 joerg 1711 1.1 joerg ConstantInitBuilder builder(CGM); 1712 1.1 joerg auto metaclassFields = builder.beginStruct(); 1713 1.1 joerg // struct objc_class *isa; 1714 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1715 1.1 joerg // struct objc_class *super_class; 1716 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1717 1.1 joerg // const char *name; 1718 1.1 joerg metaclassFields.add(classNameConstant); 1719 1.1 joerg // long version; 1720 1.1 joerg metaclassFields.addInt(LongTy, 0); 1721 1.1 joerg // unsigned long info; 1722 1.1 joerg // objc_class_flag_meta 1723 1.1 joerg metaclassFields.addInt(LongTy, 1); 1724 1.1 joerg // long instance_size; 1725 1.1 joerg // Setting this to zero is consistent with the older ABI, but it might be 1726 1.1 joerg // more sensible to set this to sizeof(struct objc_class) 1727 1.1 joerg metaclassFields.addInt(LongTy, 0); 1728 1.1 joerg // struct objc_ivar_list *ivars; 1729 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1730 1.1 joerg // struct objc_method_list *methods 1731 1.1 joerg // FIXME: Almost identical code is copied and pasted below for the 1732 1.1 joerg // class, but refactoring it cleanly requires C++14 generic lambdas. 1733 1.1 joerg if (OID->classmeth_begin() == OID->classmeth_end()) 1734 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1735 1.1 joerg else { 1736 1.1 joerg SmallVector<ObjCMethodDecl*, 16> ClassMethods; 1737 1.1 joerg ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(), 1738 1.1 joerg OID->classmeth_end()); 1739 1.1 joerg metaclassFields.addBitCast( 1740 1.1 joerg GenerateMethodList(className, "", ClassMethods, true), 1741 1.1 joerg PtrTy); 1742 1.1 joerg } 1743 1.1 joerg // void *dtable; 1744 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1745 1.1 joerg // IMP cxx_construct; 1746 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1747 1.1 joerg // IMP cxx_destruct; 1748 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1749 1.1 joerg // struct objc_class *subclass_list 1750 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1751 1.1 joerg // struct objc_class *sibling_class 1752 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1753 1.1 joerg // struct objc_protocol_list *protocols; 1754 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1755 1.1 joerg // struct reference_list *extra_data; 1756 1.1 joerg metaclassFields.addNullPointer(PtrTy); 1757 1.1 joerg // long abi_version; 1758 1.1 joerg metaclassFields.addInt(LongTy, 0); 1759 1.1 joerg // struct objc_property_list *properties 1760 1.1 joerg metaclassFields.add(GeneratePropertyList(OID, classDecl, /*isClassProperty*/true)); 1761 1.1 joerg 1762 1.1 joerg auto *metaclass = metaclassFields.finishAndCreateGlobal( 1763 1.1 joerg ManglePublicSymbol("OBJC_METACLASS_") + className, 1764 1.1 joerg CGM.getPointerAlign()); 1765 1.1 joerg 1766 1.1 joerg auto classFields = builder.beginStruct(); 1767 1.1 joerg // struct objc_class *isa; 1768 1.1 joerg classFields.add(metaclass); 1769 1.1 joerg // struct objc_class *super_class; 1770 1.1 joerg // Get the superclass name. 1771 1.1 joerg const ObjCInterfaceDecl * SuperClassDecl = 1772 1.1 joerg OID->getClassInterface()->getSuperClass(); 1773 1.1 joerg llvm::Constant *SuperClass = nullptr; 1774 1.1 joerg if (SuperClassDecl) { 1775 1.1 joerg auto SuperClassName = SymbolForClass(SuperClassDecl->getNameAsString()); 1776 1.1 joerg SuperClass = TheModule.getNamedGlobal(SuperClassName); 1777 1.1 joerg if (!SuperClass) 1778 1.1 joerg { 1779 1.1 joerg SuperClass = new llvm::GlobalVariable(TheModule, PtrTy, false, 1780 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, SuperClassName); 1781 1.1 joerg if (IsCOFF) { 1782 1.1 joerg auto Storage = llvm::GlobalValue::DefaultStorageClass; 1783 1.1 joerg if (SuperClassDecl->hasAttr<DLLImportAttr>()) 1784 1.1 joerg Storage = llvm::GlobalValue::DLLImportStorageClass; 1785 1.1 joerg else if (SuperClassDecl->hasAttr<DLLExportAttr>()) 1786 1.1 joerg Storage = llvm::GlobalValue::DLLExportStorageClass; 1787 1.1 joerg 1788 1.1 joerg cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage); 1789 1.1 joerg } 1790 1.1 joerg } 1791 1.1 joerg if (!IsCOFF) 1792 1.1 joerg classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy)); 1793 1.1 joerg else 1794 1.1 joerg classFields.addNullPointer(PtrTy); 1795 1.1 joerg } else 1796 1.1 joerg classFields.addNullPointer(PtrTy); 1797 1.1 joerg // const char *name; 1798 1.1 joerg classFields.add(classNameConstant); 1799 1.1 joerg // long version; 1800 1.1 joerg classFields.addInt(LongTy, 0); 1801 1.1 joerg // unsigned long info; 1802 1.1 joerg // !objc_class_flag_meta 1803 1.1 joerg classFields.addInt(LongTy, 0); 1804 1.1 joerg // long instance_size; 1805 1.1 joerg int superInstanceSize = !SuperClassDecl ? 0 : 1806 1.1 joerg Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity(); 1807 1.1 joerg // Instance size is negative for classes that have not yet had their ivar 1808 1.1 joerg // layout calculated. 1809 1.1 joerg classFields.addInt(LongTy, 1810 1.1 joerg 0 - (Context.getASTObjCImplementationLayout(OID).getSize().getQuantity() - 1811 1.1 joerg superInstanceSize)); 1812 1.1 joerg 1813 1.1 joerg if (classDecl->all_declared_ivar_begin() == nullptr) 1814 1.1 joerg classFields.addNullPointer(PtrTy); 1815 1.1 joerg else { 1816 1.1 joerg int ivar_count = 0; 1817 1.1 joerg for (const ObjCIvarDecl *IVD = classDecl->all_declared_ivar_begin(); IVD; 1818 1.1 joerg IVD = IVD->getNextIvar()) ivar_count++; 1819 1.1 joerg llvm::DataLayout td(&TheModule); 1820 1.1 joerg // struct objc_ivar_list *ivars; 1821 1.1 joerg ConstantInitBuilder b(CGM); 1822 1.1 joerg auto ivarListBuilder = b.beginStruct(); 1823 1.1 joerg // int count; 1824 1.1 joerg ivarListBuilder.addInt(IntTy, ivar_count); 1825 1.1 joerg // size_t size; 1826 1.1 joerg llvm::StructType *ObjCIvarTy = llvm::StructType::get( 1827 1.1 joerg PtrToInt8Ty, 1828 1.1 joerg PtrToInt8Ty, 1829 1.1 joerg PtrToInt8Ty, 1830 1.1 joerg Int32Ty, 1831 1.1 joerg Int32Ty); 1832 1.1 joerg ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) / 1833 1.1 joerg CGM.getContext().getCharWidth()); 1834 1.1 joerg // struct objc_ivar ivars[] 1835 1.1 joerg auto ivarArrayBuilder = ivarListBuilder.beginArray(); 1836 1.1 joerg for (const ObjCIvarDecl *IVD = classDecl->all_declared_ivar_begin(); IVD; 1837 1.1 joerg IVD = IVD->getNextIvar()) { 1838 1.1 joerg auto ivarTy = IVD->getType(); 1839 1.1 joerg auto ivarBuilder = ivarArrayBuilder.beginStruct(); 1840 1.1 joerg // const char *name; 1841 1.1 joerg ivarBuilder.add(MakeConstantString(IVD->getNameAsString())); 1842 1.1 joerg // const char *type; 1843 1.1 joerg std::string TypeStr; 1844 1.1 joerg //Context.getObjCEncodingForType(ivarTy, TypeStr, IVD, true); 1845 1.1 joerg Context.getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, ivarTy, TypeStr, true); 1846 1.1 joerg ivarBuilder.add(MakeConstantString(TypeStr)); 1847 1.1 joerg // int *offset; 1848 1.1 joerg uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD); 1849 1.1 joerg uint64_t Offset = BaseOffset - superInstanceSize; 1850 1.1 joerg llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset); 1851 1.1 joerg std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD); 1852 1.1 joerg llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName); 1853 1.1 joerg if (OffsetVar) 1854 1.1 joerg OffsetVar->setInitializer(OffsetValue); 1855 1.1 joerg else 1856 1.1 joerg OffsetVar = new llvm::GlobalVariable(TheModule, IntTy, 1857 1.1 joerg false, llvm::GlobalValue::ExternalLinkage, 1858 1.1 joerg OffsetValue, OffsetName); 1859 1.1 joerg auto ivarVisibility = 1860 1.1 joerg (IVD->getAccessControl() == ObjCIvarDecl::Private || 1861 1.1 joerg IVD->getAccessControl() == ObjCIvarDecl::Package || 1862 1.1 joerg classDecl->getVisibility() == HiddenVisibility) ? 1863 1.1 joerg llvm::GlobalValue::HiddenVisibility : 1864 1.1 joerg llvm::GlobalValue::DefaultVisibility; 1865 1.1 joerg OffsetVar->setVisibility(ivarVisibility); 1866 1.1 joerg ivarBuilder.add(OffsetVar); 1867 1.1 joerg // Ivar size 1868 1.1 joerg ivarBuilder.addInt(Int32Ty, 1869 1.1 joerg CGM.getContext().getTypeSizeInChars(ivarTy).getQuantity()); 1870 1.1 joerg // Alignment will be stored as a base-2 log of the alignment. 1871 1.1 joerg unsigned align = 1872 1.1 joerg llvm::Log2_32(Context.getTypeAlignInChars(ivarTy).getQuantity()); 1873 1.1 joerg // Objects that require more than 2^64-byte alignment should be impossible! 1874 1.1 joerg assert(align < 64); 1875 1.1 joerg // uint32_t flags; 1876 1.1 joerg // Bits 0-1 are ownership. 1877 1.1 joerg // Bit 2 indicates an extended type encoding 1878 1.1 joerg // Bits 3-8 contain log2(aligment) 1879 1.1 joerg ivarBuilder.addInt(Int32Ty, 1880 1.1 joerg (align << 3) | (1<<2) | 1881 1.1 joerg FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime())); 1882 1.1 joerg ivarBuilder.finishAndAddTo(ivarArrayBuilder); 1883 1.1 joerg } 1884 1.1 joerg ivarArrayBuilder.finishAndAddTo(ivarListBuilder); 1885 1.1 joerg auto ivarList = ivarListBuilder.finishAndCreateGlobal(".objc_ivar_list", 1886 1.1 joerg CGM.getPointerAlign(), /*constant*/ false, 1887 1.1 joerg llvm::GlobalValue::PrivateLinkage); 1888 1.1 joerg classFields.add(ivarList); 1889 1.1 joerg } 1890 1.1 joerg // struct objc_method_list *methods 1891 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> InstanceMethods; 1892 1.1 joerg InstanceMethods.insert(InstanceMethods.begin(), OID->instmeth_begin(), 1893 1.1 joerg OID->instmeth_end()); 1894 1.1 joerg for (auto *propImpl : OID->property_impls()) 1895 1.1 joerg if (propImpl->getPropertyImplementation() == 1896 1.1 joerg ObjCPropertyImplDecl::Synthesize) { 1897 1.1.1.2 joerg auto addIfExists = [&](const ObjCMethodDecl *OMD) { 1898 1.1.1.2 joerg if (OMD && OMD->hasBody()) 1899 1.1 joerg InstanceMethods.push_back(OMD); 1900 1.1 joerg }; 1901 1.1.1.2 joerg addIfExists(propImpl->getGetterMethodDecl()); 1902 1.1.1.2 joerg addIfExists(propImpl->getSetterMethodDecl()); 1903 1.1 joerg } 1904 1.1 joerg 1905 1.1 joerg if (InstanceMethods.size() == 0) 1906 1.1 joerg classFields.addNullPointer(PtrTy); 1907 1.1 joerg else 1908 1.1 joerg classFields.addBitCast( 1909 1.1 joerg GenerateMethodList(className, "", InstanceMethods, false), 1910 1.1 joerg PtrTy); 1911 1.1 joerg // void *dtable; 1912 1.1 joerg classFields.addNullPointer(PtrTy); 1913 1.1 joerg // IMP cxx_construct; 1914 1.1 joerg classFields.addNullPointer(PtrTy); 1915 1.1 joerg // IMP cxx_destruct; 1916 1.1 joerg classFields.addNullPointer(PtrTy); 1917 1.1 joerg // struct objc_class *subclass_list 1918 1.1 joerg classFields.addNullPointer(PtrTy); 1919 1.1 joerg // struct objc_class *sibling_class 1920 1.1 joerg classFields.addNullPointer(PtrTy); 1921 1.1 joerg // struct objc_protocol_list *protocols; 1922 1.1.1.2 joerg auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->protocol_begin(), 1923 1.1.1.2 joerg classDecl->protocol_end()); 1924 1.1.1.2 joerg SmallVector<llvm::Constant *, 16> Protocols; 1925 1.1.1.2 joerg for (const auto *I : RuntimeProtocols) 1926 1.1 joerg Protocols.push_back( 1927 1.1 joerg llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I), 1928 1.1 joerg ProtocolPtrTy)); 1929 1.1 joerg if (Protocols.empty()) 1930 1.1 joerg classFields.addNullPointer(PtrTy); 1931 1.1 joerg else 1932 1.1 joerg classFields.add(GenerateProtocolList(Protocols)); 1933 1.1 joerg // struct reference_list *extra_data; 1934 1.1 joerg classFields.addNullPointer(PtrTy); 1935 1.1 joerg // long abi_version; 1936 1.1 joerg classFields.addInt(LongTy, 0); 1937 1.1 joerg // struct objc_property_list *properties 1938 1.1 joerg classFields.add(GeneratePropertyList(OID, classDecl)); 1939 1.1 joerg 1940 1.1 joerg auto *classStruct = 1941 1.1 joerg classFields.finishAndCreateGlobal(SymbolForClass(className), 1942 1.1 joerg CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage); 1943 1.1 joerg 1944 1.1 joerg auto *classRefSymbol = GetClassVar(className); 1945 1.1 joerg classRefSymbol->setSection(sectionName<ClassReferenceSection>()); 1946 1.1 joerg classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy)); 1947 1.1 joerg 1948 1.1 joerg if (IsCOFF) { 1949 1.1 joerg // we can't import a class struct. 1950 1.1 joerg if (OID->getClassInterface()->hasAttr<DLLExportAttr>()) { 1951 1.1 joerg cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 1952 1.1 joerg cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 1953 1.1 joerg } 1954 1.1 joerg 1955 1.1 joerg if (SuperClass) { 1956 1.1 joerg std::pair<llvm::Constant*, int> v{classStruct, 1}; 1957 1.1.1.2 joerg EarlyInitList.emplace_back(std::string(SuperClass->getName()), 1958 1.1.1.2 joerg std::move(v)); 1959 1.1 joerg } 1960 1.1 joerg 1961 1.1 joerg } 1962 1.1 joerg 1963 1.1 joerg 1964 1.1 joerg // Resolve the class aliases, if they exist. 1965 1.1 joerg // FIXME: Class pointer aliases shouldn't exist! 1966 1.1 joerg if (ClassPtrAlias) { 1967 1.1 joerg ClassPtrAlias->replaceAllUsesWith( 1968 1.1 joerg llvm::ConstantExpr::getBitCast(classStruct, IdTy)); 1969 1.1 joerg ClassPtrAlias->eraseFromParent(); 1970 1.1 joerg ClassPtrAlias = nullptr; 1971 1.1 joerg } 1972 1.1 joerg if (auto Placeholder = 1973 1.1 joerg TheModule.getNamedGlobal(SymbolForClass(className))) 1974 1.1 joerg if (Placeholder != classStruct) { 1975 1.1 joerg Placeholder->replaceAllUsesWith( 1976 1.1 joerg llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType())); 1977 1.1 joerg Placeholder->eraseFromParent(); 1978 1.1 joerg classStruct->setName(SymbolForClass(className)); 1979 1.1 joerg } 1980 1.1 joerg if (MetaClassPtrAlias) { 1981 1.1 joerg MetaClassPtrAlias->replaceAllUsesWith( 1982 1.1 joerg llvm::ConstantExpr::getBitCast(metaclass, IdTy)); 1983 1.1 joerg MetaClassPtrAlias->eraseFromParent(); 1984 1.1 joerg MetaClassPtrAlias = nullptr; 1985 1.1 joerg } 1986 1.1 joerg assert(classStruct->getName() == SymbolForClass(className)); 1987 1.1 joerg 1988 1.1 joerg auto classInitRef = new llvm::GlobalVariable(TheModule, 1989 1.1 joerg classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage, 1990 1.1 joerg classStruct, ManglePublicSymbol("OBJC_INIT_CLASS_") + className); 1991 1.1 joerg classInitRef->setSection(sectionName<ClassSection>()); 1992 1.1 joerg CGM.addUsedGlobal(classInitRef); 1993 1.1 joerg 1994 1.1 joerg EmittedClass = true; 1995 1.1 joerg } 1996 1.1 joerg public: 1997 1.1 joerg CGObjCGNUstep2(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) { 1998 1.1 joerg MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, 1999 1.1 joerg PtrToObjCSuperTy, SelectorTy); 2000 1.1 joerg // struct objc_property 2001 1.1 joerg // { 2002 1.1 joerg // const char *name; 2003 1.1 joerg // const char *attributes; 2004 1.1 joerg // const char *type; 2005 1.1 joerg // SEL getter; 2006 1.1 joerg // SEL setter; 2007 1.1 joerg // } 2008 1.1 joerg PropertyMetadataTy = 2009 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), 2010 1.1 joerg { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty }); 2011 1.1 joerg } 2012 1.1 joerg 2013 1.1 joerg }; 2014 1.1 joerg 2015 1.1 joerg const char *const CGObjCGNUstep2::SectionsBaseNames[8] = 2016 1.1 joerg { 2017 1.1 joerg "__objc_selectors", 2018 1.1 joerg "__objc_classes", 2019 1.1 joerg "__objc_class_refs", 2020 1.1 joerg "__objc_cats", 2021 1.1 joerg "__objc_protocols", 2022 1.1 joerg "__objc_protocol_refs", 2023 1.1 joerg "__objc_class_aliases", 2024 1.1 joerg "__objc_constant_string" 2025 1.1 joerg }; 2026 1.1 joerg 2027 1.1 joerg const char *const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] = 2028 1.1 joerg { 2029 1.1 joerg ".objcrt$SEL", 2030 1.1 joerg ".objcrt$CLS", 2031 1.1 joerg ".objcrt$CLR", 2032 1.1 joerg ".objcrt$CAT", 2033 1.1 joerg ".objcrt$PCL", 2034 1.1 joerg ".objcrt$PCR", 2035 1.1 joerg ".objcrt$CAL", 2036 1.1 joerg ".objcrt$STR" 2037 1.1 joerg }; 2038 1.1 joerg 2039 1.1 joerg /// Support for the ObjFW runtime. 2040 1.1 joerg class CGObjCObjFW: public CGObjCGNU { 2041 1.1 joerg protected: 2042 1.1 joerg /// The GCC ABI message lookup function. Returns an IMP pointing to the 2043 1.1 joerg /// method implementation for this message. 2044 1.1 joerg LazyRuntimeFunction MsgLookupFn; 2045 1.1 joerg /// stret lookup function. While this does not seem to make sense at the 2046 1.1 joerg /// first look, this is required to call the correct forwarding function. 2047 1.1 joerg LazyRuntimeFunction MsgLookupFnSRet; 2048 1.1 joerg /// The GCC ABI superclass message lookup function. Takes a pointer to a 2049 1.1 joerg /// structure describing the receiver and the class, and a selector as 2050 1.1 joerg /// arguments. Returns the IMP for the corresponding method. 2051 1.1 joerg LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet; 2052 1.1 joerg 2053 1.1 joerg llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, 2054 1.1 joerg llvm::Value *cmd, llvm::MDNode *node, 2055 1.1 joerg MessageSendInfo &MSI) override { 2056 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 2057 1.1 joerg llvm::Value *args[] = { 2058 1.1 joerg EnforceType(Builder, Receiver, IdTy), 2059 1.1 joerg EnforceType(Builder, cmd, SelectorTy) }; 2060 1.1 joerg 2061 1.1 joerg llvm::CallBase *imp; 2062 1.1 joerg if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) 2063 1.1 joerg imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFnSRet, args); 2064 1.1 joerg else 2065 1.1 joerg imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); 2066 1.1 joerg 2067 1.1 joerg imp->setMetadata(msgSendMDKind, node); 2068 1.1 joerg return imp; 2069 1.1 joerg } 2070 1.1 joerg 2071 1.1 joerg llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, 2072 1.1 joerg llvm::Value *cmd, MessageSendInfo &MSI) override { 2073 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 2074 1.1 joerg llvm::Value *lookupArgs[] = { 2075 1.1 joerg EnforceType(Builder, ObjCSuper.getPointer(), PtrToObjCSuperTy), cmd, 2076 1.1 joerg }; 2077 1.1 joerg 2078 1.1 joerg if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) 2079 1.1 joerg return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFnSRet, lookupArgs); 2080 1.1 joerg else 2081 1.1 joerg return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); 2082 1.1 joerg } 2083 1.1 joerg 2084 1.1 joerg llvm::Value *GetClassNamed(CodeGenFunction &CGF, const std::string &Name, 2085 1.1 joerg bool isWeak) override { 2086 1.1 joerg if (isWeak) 2087 1.1 joerg return CGObjCGNU::GetClassNamed(CGF, Name, isWeak); 2088 1.1 joerg 2089 1.1 joerg EmitClassRef(Name); 2090 1.1 joerg std::string SymbolName = "_OBJC_CLASS_" + Name; 2091 1.1 joerg llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName); 2092 1.1 joerg if (!ClassSymbol) 2093 1.1 joerg ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, 2094 1.1 joerg llvm::GlobalValue::ExternalLinkage, 2095 1.1 joerg nullptr, SymbolName); 2096 1.1 joerg return ClassSymbol; 2097 1.1 joerg } 2098 1.1 joerg 2099 1.1 joerg public: 2100 1.1 joerg CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) { 2101 1.1 joerg // IMP objc_msg_lookup(id, SEL); 2102 1.1 joerg MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy); 2103 1.1 joerg MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy, 2104 1.1 joerg SelectorTy); 2105 1.1 joerg // IMP objc_msg_lookup_super(struct objc_super*, SEL); 2106 1.1 joerg MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, 2107 1.1 joerg PtrToObjCSuperTy, SelectorTy); 2108 1.1 joerg MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy, 2109 1.1 joerg PtrToObjCSuperTy, SelectorTy); 2110 1.1 joerg } 2111 1.1 joerg }; 2112 1.1 joerg } // end anonymous namespace 2113 1.1 joerg 2114 1.1 joerg /// Emits a reference to a dummy variable which is emitted with each class. 2115 1.1 joerg /// This ensures that a linker error will be generated when trying to link 2116 1.1 joerg /// together modules where a referenced class is not defined. 2117 1.1 joerg void CGObjCGNU::EmitClassRef(const std::string &className) { 2118 1.1 joerg std::string symbolRef = "__objc_class_ref_" + className; 2119 1.1 joerg // Don't emit two copies of the same symbol 2120 1.1 joerg if (TheModule.getGlobalVariable(symbolRef)) 2121 1.1 joerg return; 2122 1.1 joerg std::string symbolName = "__objc_class_name_" + className; 2123 1.1 joerg llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName); 2124 1.1 joerg if (!ClassSymbol) { 2125 1.1 joerg ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, 2126 1.1 joerg llvm::GlobalValue::ExternalLinkage, 2127 1.1 joerg nullptr, symbolName); 2128 1.1 joerg } 2129 1.1 joerg new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true, 2130 1.1 joerg llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef); 2131 1.1 joerg } 2132 1.1 joerg 2133 1.1 joerg CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion, 2134 1.1 joerg unsigned protocolClassVersion, unsigned classABI) 2135 1.1 joerg : CGObjCRuntime(cgm), TheModule(CGM.getModule()), 2136 1.1 joerg VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr), 2137 1.1 joerg MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion), 2138 1.1 joerg ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) { 2139 1.1 joerg 2140 1.1 joerg msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend"); 2141 1.1 joerg usesSEHExceptions = 2142 1.1 joerg cgm.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment(); 2143 1.1 joerg 2144 1.1 joerg CodeGenTypes &Types = CGM.getTypes(); 2145 1.1 joerg IntTy = cast<llvm::IntegerType>( 2146 1.1 joerg Types.ConvertType(CGM.getContext().IntTy)); 2147 1.1 joerg LongTy = cast<llvm::IntegerType>( 2148 1.1 joerg Types.ConvertType(CGM.getContext().LongTy)); 2149 1.1 joerg SizeTy = cast<llvm::IntegerType>( 2150 1.1 joerg Types.ConvertType(CGM.getContext().getSizeType())); 2151 1.1 joerg PtrDiffTy = cast<llvm::IntegerType>( 2152 1.1 joerg Types.ConvertType(CGM.getContext().getPointerDiffType())); 2153 1.1 joerg BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 2154 1.1 joerg 2155 1.1 joerg Int8Ty = llvm::Type::getInt8Ty(VMContext); 2156 1.1 joerg // C string type. Used in lots of places. 2157 1.1 joerg PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 2158 1.1 joerg ProtocolPtrTy = llvm::PointerType::getUnqual( 2159 1.1 joerg Types.ConvertType(CGM.getContext().getObjCProtoType())); 2160 1.1 joerg 2161 1.1 joerg Zeros[0] = llvm::ConstantInt::get(LongTy, 0); 2162 1.1 joerg Zeros[1] = Zeros[0]; 2163 1.1 joerg NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty); 2164 1.1 joerg // Get the selector Type. 2165 1.1 joerg QualType selTy = CGM.getContext().getObjCSelType(); 2166 1.1 joerg if (QualType() == selTy) { 2167 1.1 joerg SelectorTy = PtrToInt8Ty; 2168 1.1 joerg } else { 2169 1.1 joerg SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy)); 2170 1.1 joerg } 2171 1.1 joerg 2172 1.1 joerg PtrToIntTy = llvm::PointerType::getUnqual(IntTy); 2173 1.1 joerg PtrTy = PtrToInt8Ty; 2174 1.1 joerg 2175 1.1 joerg Int32Ty = llvm::Type::getInt32Ty(VMContext); 2176 1.1 joerg Int64Ty = llvm::Type::getInt64Ty(VMContext); 2177 1.1 joerg 2178 1.1 joerg IntPtrTy = 2179 1.1 joerg CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty; 2180 1.1 joerg 2181 1.1 joerg // Object type 2182 1.1 joerg QualType UnqualIdTy = CGM.getContext().getObjCIdType(); 2183 1.1 joerg ASTIdTy = CanQualType(); 2184 1.1 joerg if (UnqualIdTy != QualType()) { 2185 1.1 joerg ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy); 2186 1.1 joerg IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); 2187 1.1 joerg } else { 2188 1.1 joerg IdTy = PtrToInt8Ty; 2189 1.1 joerg } 2190 1.1 joerg PtrToIdTy = llvm::PointerType::getUnqual(IdTy); 2191 1.1 joerg ProtocolTy = llvm::StructType::get(IdTy, 2192 1.1 joerg PtrToInt8Ty, // name 2193 1.1 joerg PtrToInt8Ty, // protocols 2194 1.1 joerg PtrToInt8Ty, // instance methods 2195 1.1 joerg PtrToInt8Ty, // class methods 2196 1.1 joerg PtrToInt8Ty, // optional instance methods 2197 1.1 joerg PtrToInt8Ty, // optional class methods 2198 1.1 joerg PtrToInt8Ty, // properties 2199 1.1 joerg PtrToInt8Ty);// optional properties 2200 1.1 joerg 2201 1.1 joerg // struct objc_property_gsv1 2202 1.1 joerg // { 2203 1.1 joerg // const char *name; 2204 1.1 joerg // char attributes; 2205 1.1 joerg // char attributes2; 2206 1.1 joerg // char unused1; 2207 1.1 joerg // char unused2; 2208 1.1 joerg // const char *getter_name; 2209 1.1 joerg // const char *getter_types; 2210 1.1 joerg // const char *setter_name; 2211 1.1 joerg // const char *setter_types; 2212 1.1 joerg // } 2213 1.1 joerg PropertyMetadataTy = llvm::StructType::get(CGM.getLLVMContext(), { 2214 1.1 joerg PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, 2215 1.1 joerg PtrToInt8Ty, PtrToInt8Ty }); 2216 1.1 joerg 2217 1.1 joerg ObjCSuperTy = llvm::StructType::get(IdTy, IdTy); 2218 1.1 joerg PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy); 2219 1.1 joerg 2220 1.1 joerg llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); 2221 1.1 joerg 2222 1.1 joerg // void objc_exception_throw(id); 2223 1.1 joerg ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy); 2224 1.1 joerg ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy); 2225 1.1 joerg // int objc_sync_enter(id); 2226 1.1 joerg SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy); 2227 1.1 joerg // int objc_sync_exit(id); 2228 1.1 joerg SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy); 2229 1.1 joerg 2230 1.1 joerg // void objc_enumerationMutation (id) 2231 1.1 joerg EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy, IdTy); 2232 1.1 joerg 2233 1.1 joerg // id objc_getProperty(id, SEL, ptrdiff_t, BOOL) 2234 1.1 joerg GetPropertyFn.init(&CGM, "objc_getProperty", IdTy, IdTy, SelectorTy, 2235 1.1 joerg PtrDiffTy, BoolTy); 2236 1.1 joerg // void objc_setProperty(id, SEL, ptrdiff_t, id, BOOL, BOOL) 2237 1.1 joerg SetPropertyFn.init(&CGM, "objc_setProperty", VoidTy, IdTy, SelectorTy, 2238 1.1 joerg PtrDiffTy, IdTy, BoolTy, BoolTy); 2239 1.1 joerg // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL) 2240 1.1 joerg GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy, 2241 1.1 joerg PtrDiffTy, BoolTy, BoolTy); 2242 1.1 joerg // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL) 2243 1.1 joerg SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy, 2244 1.1 joerg PtrDiffTy, BoolTy, BoolTy); 2245 1.1 joerg 2246 1.1 joerg // IMP type 2247 1.1 joerg llvm::Type *IMPArgs[] = { IdTy, SelectorTy }; 2248 1.1 joerg IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs, 2249 1.1 joerg true)); 2250 1.1 joerg 2251 1.1 joerg const LangOptions &Opts = CGM.getLangOpts(); 2252 1.1 joerg if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount) 2253 1.1 joerg RuntimeVersion = 10; 2254 1.1 joerg 2255 1.1 joerg // Don't bother initialising the GC stuff unless we're compiling in GC mode 2256 1.1 joerg if (Opts.getGC() != LangOptions::NonGC) { 2257 1.1 joerg // This is a bit of an hack. We should sort this out by having a proper 2258 1.1 joerg // CGObjCGNUstep subclass for GC, but we may want to really support the old 2259 1.1 joerg // ABI and GC added in ObjectiveC2.framework, so we fudge it a bit for now 2260 1.1 joerg // Get selectors needed in GC mode 2261 1.1 joerg RetainSel = GetNullarySelector("retain", CGM.getContext()); 2262 1.1 joerg ReleaseSel = GetNullarySelector("release", CGM.getContext()); 2263 1.1 joerg AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext()); 2264 1.1 joerg 2265 1.1 joerg // Get functions needed in GC mode 2266 1.1 joerg 2267 1.1 joerg // id objc_assign_ivar(id, id, ptrdiff_t); 2268 1.1 joerg IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy); 2269 1.1 joerg // id objc_assign_strongCast (id, id*) 2270 1.1 joerg StrongCastAssignFn.init(&CGM, "objc_assign_strongCast", IdTy, IdTy, 2271 1.1 joerg PtrToIdTy); 2272 1.1 joerg // id objc_assign_global(id, id*); 2273 1.1 joerg GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy); 2274 1.1 joerg // id objc_assign_weak(id, id*); 2275 1.1 joerg WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy); 2276 1.1 joerg // id objc_read_weak(id*); 2277 1.1 joerg WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy); 2278 1.1 joerg // void *objc_memmove_collectable(void*, void *, size_t); 2279 1.1 joerg MemMoveFn.init(&CGM, "objc_memmove_collectable", PtrTy, PtrTy, PtrTy, 2280 1.1 joerg SizeTy); 2281 1.1 joerg } 2282 1.1 joerg } 2283 1.1 joerg 2284 1.1 joerg llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF, 2285 1.1 joerg const std::string &Name, bool isWeak) { 2286 1.1 joerg llvm::Constant *ClassName = MakeConstantString(Name); 2287 1.1 joerg // With the incompatible ABI, this will need to be replaced with a direct 2288 1.1 joerg // reference to the class symbol. For the compatible nonfragile ABI we are 2289 1.1 joerg // still performing this lookup at run time but emitting the symbol for the 2290 1.1 joerg // class externally so that we can make the switch later. 2291 1.1 joerg // 2292 1.1 joerg // Libobjc2 contains an LLVM pass that replaces calls to objc_lookup_class 2293 1.1 joerg // with memoized versions or with static references if it's safe to do so. 2294 1.1 joerg if (!isWeak) 2295 1.1 joerg EmitClassRef(Name); 2296 1.1 joerg 2297 1.1 joerg llvm::FunctionCallee ClassLookupFn = CGM.CreateRuntimeFunction( 2298 1.1 joerg llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), "objc_lookup_class"); 2299 1.1 joerg return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName); 2300 1.1 joerg } 2301 1.1 joerg 2302 1.1 joerg // This has to perform the lookup every time, since posing and related 2303 1.1 joerg // techniques can modify the name -> class mapping. 2304 1.1 joerg llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF, 2305 1.1 joerg const ObjCInterfaceDecl *OID) { 2306 1.1 joerg auto *Value = 2307 1.1 joerg GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported()); 2308 1.1 joerg if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value)) 2309 1.1 joerg CGM.setGVProperties(ClassSymbol, OID); 2310 1.1 joerg return Value; 2311 1.1 joerg } 2312 1.1 joerg 2313 1.1 joerg llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 2314 1.1 joerg auto *Value = GetClassNamed(CGF, "NSAutoreleasePool", false); 2315 1.1 joerg if (CGM.getTriple().isOSBinFormatCOFF()) { 2316 1.1 joerg if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value)) { 2317 1.1 joerg IdentifierInfo &II = CGF.CGM.getContext().Idents.get("NSAutoreleasePool"); 2318 1.1 joerg TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 2319 1.1 joerg DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 2320 1.1 joerg 2321 1.1 joerg const VarDecl *VD = nullptr; 2322 1.1.1.2 joerg for (const auto *Result : DC->lookup(&II)) 2323 1.1 joerg if ((VD = dyn_cast<VarDecl>(Result))) 2324 1.1 joerg break; 2325 1.1 joerg 2326 1.1 joerg CGM.setGVProperties(ClassSymbol, VD); 2327 1.1 joerg } 2328 1.1 joerg } 2329 1.1 joerg return Value; 2330 1.1 joerg } 2331 1.1 joerg 2332 1.1 joerg llvm::Value *CGObjCGNU::GetTypedSelector(CodeGenFunction &CGF, Selector Sel, 2333 1.1 joerg const std::string &TypeEncoding) { 2334 1.1 joerg SmallVectorImpl<TypedSelector> &Types = SelectorTable[Sel]; 2335 1.1 joerg llvm::GlobalAlias *SelValue = nullptr; 2336 1.1 joerg 2337 1.1 joerg for (SmallVectorImpl<TypedSelector>::iterator i = Types.begin(), 2338 1.1 joerg e = Types.end() ; i!=e ; i++) { 2339 1.1 joerg if (i->first == TypeEncoding) { 2340 1.1 joerg SelValue = i->second; 2341 1.1 joerg break; 2342 1.1 joerg } 2343 1.1 joerg } 2344 1.1 joerg if (!SelValue) { 2345 1.1 joerg SelValue = llvm::GlobalAlias::create( 2346 1.1 joerg SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage, 2347 1.1 joerg ".objc_selector_" + Sel.getAsString(), &TheModule); 2348 1.1 joerg Types.emplace_back(TypeEncoding, SelValue); 2349 1.1 joerg } 2350 1.1 joerg 2351 1.1 joerg return SelValue; 2352 1.1 joerg } 2353 1.1 joerg 2354 1.1 joerg Address CGObjCGNU::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) { 2355 1.1 joerg llvm::Value *SelValue = GetSelector(CGF, Sel); 2356 1.1 joerg 2357 1.1 joerg // Store it to a temporary. Does this satisfy the semantics of 2358 1.1 joerg // GetAddrOfSelector? Hopefully. 2359 1.1 joerg Address tmp = CGF.CreateTempAlloca(SelValue->getType(), 2360 1.1 joerg CGF.getPointerAlign()); 2361 1.1 joerg CGF.Builder.CreateStore(SelValue, tmp); 2362 1.1 joerg return tmp; 2363 1.1 joerg } 2364 1.1 joerg 2365 1.1 joerg llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel) { 2366 1.1 joerg return GetTypedSelector(CGF, Sel, std::string()); 2367 1.1 joerg } 2368 1.1 joerg 2369 1.1 joerg llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, 2370 1.1 joerg const ObjCMethodDecl *Method) { 2371 1.1 joerg std::string SelTypes = CGM.getContext().getObjCEncodingForMethodDecl(Method); 2372 1.1 joerg return GetTypedSelector(CGF, Method->getSelector(), SelTypes); 2373 1.1 joerg } 2374 1.1 joerg 2375 1.1 joerg llvm::Constant *CGObjCGNU::GetEHType(QualType T) { 2376 1.1 joerg if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 2377 1.1 joerg // With the old ABI, there was only one kind of catchall, which broke 2378 1.1 joerg // foreign exceptions. With the new ABI, we use __objc_id_typeinfo as 2379 1.1 joerg // a pointer indicating object catchalls, and NULL to indicate real 2380 1.1 joerg // catchalls 2381 1.1 joerg if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { 2382 1.1 joerg return MakeConstantString("@id"); 2383 1.1 joerg } else { 2384 1.1 joerg return nullptr; 2385 1.1 joerg } 2386 1.1 joerg } 2387 1.1 joerg 2388 1.1 joerg // All other types should be Objective-C interface pointer types. 2389 1.1 joerg const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>(); 2390 1.1 joerg assert(OPT && "Invalid @catch type."); 2391 1.1 joerg const ObjCInterfaceDecl *IDecl = OPT->getObjectType()->getInterface(); 2392 1.1 joerg assert(IDecl && "Invalid @catch type."); 2393 1.1 joerg return MakeConstantString(IDecl->getIdentifier()->getName()); 2394 1.1 joerg } 2395 1.1 joerg 2396 1.1 joerg llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) { 2397 1.1 joerg if (usesSEHExceptions) 2398 1.1 joerg return CGM.getCXXABI().getAddrOfRTTIDescriptor(T); 2399 1.1 joerg 2400 1.1 joerg if (!CGM.getLangOpts().CPlusPlus) 2401 1.1 joerg return CGObjCGNU::GetEHType(T); 2402 1.1 joerg 2403 1.1 joerg // For Objective-C++, we want to provide the ability to catch both C++ and 2404 1.1 joerg // Objective-C objects in the same function. 2405 1.1 joerg 2406 1.1 joerg // There's a particular fixed type info for 'id'. 2407 1.1 joerg if (T->isObjCIdType() || 2408 1.1 joerg T->isObjCQualifiedIdType()) { 2409 1.1 joerg llvm::Constant *IDEHType = 2410 1.1 joerg CGM.getModule().getGlobalVariable("__objc_id_type_info"); 2411 1.1 joerg if (!IDEHType) 2412 1.1 joerg IDEHType = 2413 1.1 joerg new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty, 2414 1.1 joerg false, 2415 1.1 joerg llvm::GlobalValue::ExternalLinkage, 2416 1.1 joerg nullptr, "__objc_id_type_info"); 2417 1.1 joerg return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty); 2418 1.1 joerg } 2419 1.1 joerg 2420 1.1 joerg const ObjCObjectPointerType *PT = 2421 1.1 joerg T->getAs<ObjCObjectPointerType>(); 2422 1.1 joerg assert(PT && "Invalid @catch type."); 2423 1.1 joerg const ObjCInterfaceType *IT = PT->getInterfaceType(); 2424 1.1 joerg assert(IT && "Invalid @catch type."); 2425 1.1.1.2 joerg std::string className = 2426 1.1.1.2 joerg std::string(IT->getDecl()->getIdentifier()->getName()); 2427 1.1 joerg 2428 1.1 joerg std::string typeinfoName = "__objc_eh_typeinfo_" + className; 2429 1.1 joerg 2430 1.1 joerg // Return the existing typeinfo if it exists 2431 1.1 joerg llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName); 2432 1.1 joerg if (typeinfo) 2433 1.1 joerg return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty); 2434 1.1 joerg 2435 1.1 joerg // Otherwise create it. 2436 1.1 joerg 2437 1.1 joerg // vtable for gnustep::libobjc::__objc_class_type_info 2438 1.1 joerg // It's quite ugly hard-coding this. Ideally we'd generate it using the host 2439 1.1 joerg // platform's name mangling. 2440 1.1 joerg const char *vtableName = "_ZTVN7gnustep7libobjc22__objc_class_type_infoE"; 2441 1.1 joerg auto *Vtable = TheModule.getGlobalVariable(vtableName); 2442 1.1 joerg if (!Vtable) { 2443 1.1 joerg Vtable = new llvm::GlobalVariable(TheModule, PtrToInt8Ty, true, 2444 1.1 joerg llvm::GlobalValue::ExternalLinkage, 2445 1.1 joerg nullptr, vtableName); 2446 1.1 joerg } 2447 1.1 joerg llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2); 2448 1.1 joerg auto *BVtable = llvm::ConstantExpr::getBitCast( 2449 1.1 joerg llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two), 2450 1.1 joerg PtrToInt8Ty); 2451 1.1 joerg 2452 1.1 joerg llvm::Constant *typeName = 2453 1.1 joerg ExportUniqueString(className, "__objc_eh_typename_"); 2454 1.1 joerg 2455 1.1 joerg ConstantInitBuilder builder(CGM); 2456 1.1 joerg auto fields = builder.beginStruct(); 2457 1.1 joerg fields.add(BVtable); 2458 1.1 joerg fields.add(typeName); 2459 1.1 joerg llvm::Constant *TI = 2460 1.1 joerg fields.finishAndCreateGlobal("__objc_eh_typeinfo_" + className, 2461 1.1 joerg CGM.getPointerAlign(), 2462 1.1 joerg /*constant*/ false, 2463 1.1 joerg llvm::GlobalValue::LinkOnceODRLinkage); 2464 1.1 joerg return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty); 2465 1.1 joerg } 2466 1.1 joerg 2467 1.1 joerg /// Generate an NSConstantString object. 2468 1.1 joerg ConstantAddress CGObjCGNU::GenerateConstantString(const StringLiteral *SL) { 2469 1.1 joerg 2470 1.1 joerg std::string Str = SL->getString().str(); 2471 1.1 joerg CharUnits Align = CGM.getPointerAlign(); 2472 1.1 joerg 2473 1.1 joerg // Look for an existing one 2474 1.1 joerg llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str); 2475 1.1 joerg if (old != ObjCStrings.end()) 2476 1.1 joerg return ConstantAddress(old->getValue(), Align); 2477 1.1 joerg 2478 1.1 joerg StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass; 2479 1.1 joerg 2480 1.1 joerg if (StringClass.empty()) StringClass = "NSConstantString"; 2481 1.1 joerg 2482 1.1 joerg std::string Sym = "_OBJC_CLASS_"; 2483 1.1 joerg Sym += StringClass; 2484 1.1 joerg 2485 1.1 joerg llvm::Constant *isa = TheModule.getNamedGlobal(Sym); 2486 1.1 joerg 2487 1.1 joerg if (!isa) 2488 1.1 joerg isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false, 2489 1.1 joerg llvm::GlobalValue::ExternalWeakLinkage, nullptr, Sym); 2490 1.1 joerg else if (isa->getType() != PtrToIdTy) 2491 1.1 joerg isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy); 2492 1.1 joerg 2493 1.1 joerg ConstantInitBuilder Builder(CGM); 2494 1.1 joerg auto Fields = Builder.beginStruct(); 2495 1.1 joerg Fields.add(isa); 2496 1.1 joerg Fields.add(MakeConstantString(Str)); 2497 1.1 joerg Fields.addInt(IntTy, Str.size()); 2498 1.1 joerg llvm::Constant *ObjCStr = 2499 1.1 joerg Fields.finishAndCreateGlobal(".objc_str", Align); 2500 1.1 joerg ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty); 2501 1.1 joerg ObjCStrings[Str] = ObjCStr; 2502 1.1 joerg ConstantStrings.push_back(ObjCStr); 2503 1.1 joerg return ConstantAddress(ObjCStr, Align); 2504 1.1 joerg } 2505 1.1 joerg 2506 1.1 joerg ///Generates a message send where the super is the receiver. This is a message 2507 1.1 joerg ///send to self with special delivery semantics indicating which class's method 2508 1.1 joerg ///should be called. 2509 1.1 joerg RValue 2510 1.1 joerg CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, 2511 1.1 joerg ReturnValueSlot Return, 2512 1.1 joerg QualType ResultType, 2513 1.1 joerg Selector Sel, 2514 1.1 joerg const ObjCInterfaceDecl *Class, 2515 1.1 joerg bool isCategoryImpl, 2516 1.1 joerg llvm::Value *Receiver, 2517 1.1 joerg bool IsClassMessage, 2518 1.1 joerg const CallArgList &CallArgs, 2519 1.1 joerg const ObjCMethodDecl *Method) { 2520 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 2521 1.1 joerg if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 2522 1.1 joerg if (Sel == RetainSel || Sel == AutoreleaseSel) { 2523 1.1 joerg return RValue::get(EnforceType(Builder, Receiver, 2524 1.1 joerg CGM.getTypes().ConvertType(ResultType))); 2525 1.1 joerg } 2526 1.1 joerg if (Sel == ReleaseSel) { 2527 1.1 joerg return RValue::get(nullptr); 2528 1.1 joerg } 2529 1.1 joerg } 2530 1.1 joerg 2531 1.1 joerg llvm::Value *cmd = GetSelector(CGF, Sel); 2532 1.1 joerg CallArgList ActualArgs; 2533 1.1 joerg 2534 1.1 joerg ActualArgs.add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy); 2535 1.1 joerg ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType()); 2536 1.1 joerg ActualArgs.addFrom(CallArgs); 2537 1.1 joerg 2538 1.1 joerg MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); 2539 1.1 joerg 2540 1.1 joerg llvm::Value *ReceiverClass = nullptr; 2541 1.1 joerg bool isV2ABI = isRuntime(ObjCRuntime::GNUstep, 2); 2542 1.1 joerg if (isV2ABI) { 2543 1.1 joerg ReceiverClass = GetClassNamed(CGF, 2544 1.1 joerg Class->getSuperClass()->getNameAsString(), /*isWeak*/false); 2545 1.1 joerg if (IsClassMessage) { 2546 1.1 joerg // Load the isa pointer of the superclass is this is a class method. 2547 1.1 joerg ReceiverClass = Builder.CreateBitCast(ReceiverClass, 2548 1.1 joerg llvm::PointerType::getUnqual(IdTy)); 2549 1.1 joerg ReceiverClass = 2550 1.1.1.2 joerg Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.getPointerAlign()); 2551 1.1 joerg } 2552 1.1 joerg ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy); 2553 1.1 joerg } else { 2554 1.1 joerg if (isCategoryImpl) { 2555 1.1 joerg llvm::FunctionCallee classLookupFunction = nullptr; 2556 1.1 joerg if (IsClassMessage) { 2557 1.1 joerg classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 2558 1.1 joerg IdTy, PtrTy, true), "objc_get_meta_class"); 2559 1.1 joerg } else { 2560 1.1 joerg classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 2561 1.1 joerg IdTy, PtrTy, true), "objc_get_class"); 2562 1.1 joerg } 2563 1.1 joerg ReceiverClass = Builder.CreateCall(classLookupFunction, 2564 1.1 joerg MakeConstantString(Class->getNameAsString())); 2565 1.1 joerg } else { 2566 1.1 joerg // Set up global aliases for the metaclass or class pointer if they do not 2567 1.1 joerg // already exist. These will are forward-references which will be set to 2568 1.1 joerg // pointers to the class and metaclass structure created for the runtime 2569 1.1 joerg // load function. To send a message to super, we look up the value of the 2570 1.1 joerg // super_class pointer from either the class or metaclass structure. 2571 1.1 joerg if (IsClassMessage) { 2572 1.1 joerg if (!MetaClassPtrAlias) { 2573 1.1 joerg MetaClassPtrAlias = llvm::GlobalAlias::create( 2574 1.1 joerg IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage, 2575 1.1 joerg ".objc_metaclass_ref" + Class->getNameAsString(), &TheModule); 2576 1.1 joerg } 2577 1.1 joerg ReceiverClass = MetaClassPtrAlias; 2578 1.1 joerg } else { 2579 1.1 joerg if (!ClassPtrAlias) { 2580 1.1 joerg ClassPtrAlias = llvm::GlobalAlias::create( 2581 1.1 joerg IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage, 2582 1.1 joerg ".objc_class_ref" + Class->getNameAsString(), &TheModule); 2583 1.1 joerg } 2584 1.1 joerg ReceiverClass = ClassPtrAlias; 2585 1.1 joerg } 2586 1.1 joerg } 2587 1.1 joerg // Cast the pointer to a simplified version of the class structure 2588 1.1 joerg llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy); 2589 1.1 joerg ReceiverClass = Builder.CreateBitCast(ReceiverClass, 2590 1.1 joerg llvm::PointerType::getUnqual(CastTy)); 2591 1.1 joerg // Get the superclass pointer 2592 1.1 joerg ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1); 2593 1.1 joerg // Load the superclass pointer 2594 1.1 joerg ReceiverClass = 2595 1.1.1.2 joerg Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.getPointerAlign()); 2596 1.1 joerg } 2597 1.1 joerg // Construct the structure used to look up the IMP 2598 1.1 joerg llvm::StructType *ObjCSuperTy = 2599 1.1 joerg llvm::StructType::get(Receiver->getType(), IdTy); 2600 1.1 joerg 2601 1.1 joerg Address ObjCSuper = CGF.CreateTempAlloca(ObjCSuperTy, 2602 1.1 joerg CGF.getPointerAlign()); 2603 1.1 joerg 2604 1.1 joerg Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0)); 2605 1.1 joerg Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1)); 2606 1.1 joerg 2607 1.1 joerg ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy); 2608 1.1 joerg 2609 1.1 joerg // Get the IMP 2610 1.1 joerg llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI); 2611 1.1 joerg imp = EnforceType(Builder, imp, MSI.MessengerType); 2612 1.1 joerg 2613 1.1 joerg llvm::Metadata *impMD[] = { 2614 1.1 joerg llvm::MDString::get(VMContext, Sel.getAsString()), 2615 1.1 joerg llvm::MDString::get(VMContext, Class->getSuperClass()->getNameAsString()), 2616 1.1 joerg llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 2617 1.1 joerg llvm::Type::getInt1Ty(VMContext), IsClassMessage))}; 2618 1.1 joerg llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD); 2619 1.1 joerg 2620 1.1 joerg CGCallee callee(CGCalleeInfo(), imp); 2621 1.1 joerg 2622 1.1 joerg llvm::CallBase *call; 2623 1.1 joerg RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); 2624 1.1 joerg call->setMetadata(msgSendMDKind, node); 2625 1.1 joerg return msgRet; 2626 1.1 joerg } 2627 1.1 joerg 2628 1.1 joerg /// Generate code for a message send expression. 2629 1.1 joerg RValue 2630 1.1 joerg CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, 2631 1.1 joerg ReturnValueSlot Return, 2632 1.1 joerg QualType ResultType, 2633 1.1 joerg Selector Sel, 2634 1.1 joerg llvm::Value *Receiver, 2635 1.1 joerg const CallArgList &CallArgs, 2636 1.1 joerg const ObjCInterfaceDecl *Class, 2637 1.1 joerg const ObjCMethodDecl *Method) { 2638 1.1 joerg CGBuilderTy &Builder = CGF.Builder; 2639 1.1 joerg 2640 1.1 joerg // Strip out message sends to retain / release in GC mode 2641 1.1 joerg if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 2642 1.1 joerg if (Sel == RetainSel || Sel == AutoreleaseSel) { 2643 1.1 joerg return RValue::get(EnforceType(Builder, Receiver, 2644 1.1 joerg CGM.getTypes().ConvertType(ResultType))); 2645 1.1 joerg } 2646 1.1 joerg if (Sel == ReleaseSel) { 2647 1.1 joerg return RValue::get(nullptr); 2648 1.1 joerg } 2649 1.1 joerg } 2650 1.1 joerg 2651 1.1 joerg // If the return type is something that goes in an integer register, the 2652 1.1 joerg // runtime will handle 0 returns. For other cases, we fill in the 0 value 2653 1.1 joerg // ourselves. 2654 1.1 joerg // 2655 1.1 joerg // The language spec says the result of this kind of message send is 2656 1.1 joerg // undefined, but lots of people seem to have forgotten to read that 2657 1.1 joerg // paragraph and insist on sending messages to nil that have structure 2658 1.1 joerg // returns. With GCC, this generates a random return value (whatever happens 2659 1.1 joerg // to be on the stack / in those registers at the time) on most platforms, 2660 1.1 joerg // and generates an illegal instruction trap on SPARC. With LLVM it corrupts 2661 1.1 joerg // the stack. 2662 1.1 joerg bool isPointerSizedReturn = (ResultType->isAnyPointerType() || 2663 1.1 joerg ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType()); 2664 1.1 joerg 2665 1.1 joerg llvm::BasicBlock *startBB = nullptr; 2666 1.1 joerg llvm::BasicBlock *messageBB = nullptr; 2667 1.1 joerg llvm::BasicBlock *continueBB = nullptr; 2668 1.1 joerg 2669 1.1 joerg if (!isPointerSizedReturn) { 2670 1.1 joerg startBB = Builder.GetInsertBlock(); 2671 1.1 joerg messageBB = CGF.createBasicBlock("msgSend"); 2672 1.1 joerg continueBB = CGF.createBasicBlock("continue"); 2673 1.1 joerg 2674 1.1 joerg llvm::Value *isNil = Builder.CreateICmpEQ(Receiver, 2675 1.1 joerg llvm::Constant::getNullValue(Receiver->getType())); 2676 1.1 joerg Builder.CreateCondBr(isNil, continueBB, messageBB); 2677 1.1 joerg CGF.EmitBlock(messageBB); 2678 1.1 joerg } 2679 1.1 joerg 2680 1.1 joerg IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); 2681 1.1 joerg llvm::Value *cmd; 2682 1.1 joerg if (Method) 2683 1.1 joerg cmd = GetSelector(CGF, Method); 2684 1.1 joerg else 2685 1.1 joerg cmd = GetSelector(CGF, Sel); 2686 1.1 joerg cmd = EnforceType(Builder, cmd, SelectorTy); 2687 1.1 joerg Receiver = EnforceType(Builder, Receiver, IdTy); 2688 1.1 joerg 2689 1.1 joerg llvm::Metadata *impMD[] = { 2690 1.1 joerg llvm::MDString::get(VMContext, Sel.getAsString()), 2691 1.1 joerg llvm::MDString::get(VMContext, Class ? Class->getNameAsString() : ""), 2692 1.1 joerg llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 2693 1.1 joerg llvm::Type::getInt1Ty(VMContext), Class != nullptr))}; 2694 1.1 joerg llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD); 2695 1.1 joerg 2696 1.1 joerg CallArgList ActualArgs; 2697 1.1 joerg ActualArgs.add(RValue::get(Receiver), ASTIdTy); 2698 1.1 joerg ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType()); 2699 1.1 joerg ActualArgs.addFrom(CallArgs); 2700 1.1 joerg 2701 1.1 joerg MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); 2702 1.1 joerg 2703 1.1 joerg // Get the IMP to call 2704 1.1 joerg llvm::Value *imp; 2705 1.1 joerg 2706 1.1 joerg // If we have non-legacy dispatch specified, we try using the objc_msgSend() 2707 1.1 joerg // functions. These are not supported on all platforms (or all runtimes on a 2708 1.1 joerg // given platform), so we 2709 1.1 joerg switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { 2710 1.1 joerg case CodeGenOptions::Legacy: 2711 1.1 joerg imp = LookupIMP(CGF, Receiver, cmd, node, MSI); 2712 1.1 joerg break; 2713 1.1 joerg case CodeGenOptions::Mixed: 2714 1.1 joerg case CodeGenOptions::NonLegacy: 2715 1.1 joerg if (CGM.ReturnTypeUsesFPRet(ResultType)) { 2716 1.1 joerg imp = 2717 1.1 joerg CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), 2718 1.1 joerg "objc_msgSend_fpret") 2719 1.1 joerg .getCallee(); 2720 1.1 joerg } else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { 2721 1.1 joerg // The actual types here don't matter - we're going to bitcast the 2722 1.1 joerg // function anyway 2723 1.1 joerg imp = 2724 1.1 joerg CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), 2725 1.1 joerg "objc_msgSend_stret") 2726 1.1 joerg .getCallee(); 2727 1.1 joerg } else { 2728 1.1 joerg imp = CGM.CreateRuntimeFunction( 2729 1.1 joerg llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend") 2730 1.1 joerg .getCallee(); 2731 1.1 joerg } 2732 1.1 joerg } 2733 1.1 joerg 2734 1.1 joerg // Reset the receiver in case the lookup modified it 2735 1.1 joerg ActualArgs[0] = CallArg(RValue::get(Receiver), ASTIdTy); 2736 1.1 joerg 2737 1.1 joerg imp = EnforceType(Builder, imp, MSI.MessengerType); 2738 1.1 joerg 2739 1.1 joerg llvm::CallBase *call; 2740 1.1 joerg CGCallee callee(CGCalleeInfo(), imp); 2741 1.1 joerg RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); 2742 1.1 joerg call->setMetadata(msgSendMDKind, node); 2743 1.1 joerg 2744 1.1 joerg 2745 1.1 joerg if (!isPointerSizedReturn) { 2746 1.1 joerg messageBB = CGF.Builder.GetInsertBlock(); 2747 1.1 joerg CGF.Builder.CreateBr(continueBB); 2748 1.1 joerg CGF.EmitBlock(continueBB); 2749 1.1 joerg if (msgRet.isScalar()) { 2750 1.1 joerg llvm::Value *v = msgRet.getScalarVal(); 2751 1.1 joerg llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2); 2752 1.1 joerg phi->addIncoming(v, messageBB); 2753 1.1 joerg phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB); 2754 1.1 joerg msgRet = RValue::get(phi); 2755 1.1 joerg } else if (msgRet.isAggregate()) { 2756 1.1 joerg Address v = msgRet.getAggregateAddress(); 2757 1.1 joerg llvm::PHINode *phi = Builder.CreatePHI(v.getType(), 2); 2758 1.1 joerg llvm::Type *RetTy = v.getElementType(); 2759 1.1 joerg Address NullVal = CGF.CreateTempAlloca(RetTy, v.getAlignment(), "null"); 2760 1.1 joerg CGF.InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy)); 2761 1.1 joerg phi->addIncoming(v.getPointer(), messageBB); 2762 1.1 joerg phi->addIncoming(NullVal.getPointer(), startBB); 2763 1.1 joerg msgRet = RValue::getAggregate(Address(phi, v.getAlignment())); 2764 1.1 joerg } else /* isComplex() */ { 2765 1.1 joerg std::pair<llvm::Value*,llvm::Value*> v = msgRet.getComplexVal(); 2766 1.1 joerg llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2); 2767 1.1 joerg phi->addIncoming(v.first, messageBB); 2768 1.1 joerg phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()), 2769 1.1 joerg startBB); 2770 1.1 joerg llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2); 2771 1.1 joerg phi2->addIncoming(v.second, messageBB); 2772 1.1 joerg phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()), 2773 1.1 joerg startBB); 2774 1.1 joerg msgRet = RValue::getComplex(phi, phi2); 2775 1.1 joerg } 2776 1.1 joerg } 2777 1.1 joerg return msgRet; 2778 1.1 joerg } 2779 1.1 joerg 2780 1.1 joerg /// Generates a MethodList. Used in construction of a objc_class and 2781 1.1 joerg /// objc_category structures. 2782 1.1 joerg llvm::Constant *CGObjCGNU:: 2783 1.1 joerg GenerateMethodList(StringRef ClassName, 2784 1.1 joerg StringRef CategoryName, 2785 1.1 joerg ArrayRef<const ObjCMethodDecl*> Methods, 2786 1.1 joerg bool isClassMethodList) { 2787 1.1 joerg if (Methods.empty()) 2788 1.1 joerg return NULLPtr; 2789 1.1 joerg 2790 1.1 joerg ConstantInitBuilder Builder(CGM); 2791 1.1 joerg 2792 1.1 joerg auto MethodList = Builder.beginStruct(); 2793 1.1 joerg MethodList.addNullPointer(CGM.Int8PtrTy); 2794 1.1 joerg MethodList.addInt(Int32Ty, Methods.size()); 2795 1.1 joerg 2796 1.1 joerg // Get the method structure type. 2797 1.1 joerg llvm::StructType *ObjCMethodTy = 2798 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), { 2799 1.1 joerg PtrToInt8Ty, // Really a selector, but the runtime creates it us. 2800 1.1 joerg PtrToInt8Ty, // Method types 2801 1.1 joerg IMPTy // Method pointer 2802 1.1 joerg }); 2803 1.1 joerg bool isV2ABI = isRuntime(ObjCRuntime::GNUstep, 2); 2804 1.1 joerg if (isV2ABI) { 2805 1.1 joerg // size_t size; 2806 1.1 joerg llvm::DataLayout td(&TheModule); 2807 1.1 joerg MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) / 2808 1.1 joerg CGM.getContext().getCharWidth()); 2809 1.1 joerg ObjCMethodTy = 2810 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), { 2811 1.1 joerg IMPTy, // Method pointer 2812 1.1 joerg PtrToInt8Ty, // Selector 2813 1.1 joerg PtrToInt8Ty // Extended type encoding 2814 1.1 joerg }); 2815 1.1 joerg } else { 2816 1.1 joerg ObjCMethodTy = 2817 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), { 2818 1.1 joerg PtrToInt8Ty, // Really a selector, but the runtime creates it us. 2819 1.1 joerg PtrToInt8Ty, // Method types 2820 1.1 joerg IMPTy // Method pointer 2821 1.1 joerg }); 2822 1.1 joerg } 2823 1.1 joerg auto MethodArray = MethodList.beginArray(); 2824 1.1 joerg ASTContext &Context = CGM.getContext(); 2825 1.1 joerg for (const auto *OMD : Methods) { 2826 1.1 joerg llvm::Constant *FnPtr = 2827 1.1.1.2 joerg TheModule.getFunction(getSymbolNameForMethod(OMD)); 2828 1.1 joerg assert(FnPtr && "Can't generate metadata for method that doesn't exist"); 2829 1.1 joerg auto Method = MethodArray.beginStruct(ObjCMethodTy); 2830 1.1 joerg if (isV2ABI) { 2831 1.1 joerg Method.addBitCast(FnPtr, IMPTy); 2832 1.1 joerg Method.add(GetConstantSelector(OMD->getSelector(), 2833 1.1 joerg Context.getObjCEncodingForMethodDecl(OMD))); 2834 1.1 joerg Method.add(MakeConstantString(Context.getObjCEncodingForMethodDecl(OMD, true))); 2835 1.1 joerg } else { 2836 1.1 joerg Method.add(MakeConstantString(OMD->getSelector().getAsString())); 2837 1.1 joerg Method.add(MakeConstantString(Context.getObjCEncodingForMethodDecl(OMD))); 2838 1.1 joerg Method.addBitCast(FnPtr, IMPTy); 2839 1.1 joerg } 2840 1.1 joerg Method.finishAndAddTo(MethodArray); 2841 1.1 joerg } 2842 1.1 joerg MethodArray.finishAndAddTo(MethodList); 2843 1.1 joerg 2844 1.1 joerg // Create an instance of the structure 2845 1.1 joerg return MethodList.finishAndCreateGlobal(".objc_method_list", 2846 1.1 joerg CGM.getPointerAlign()); 2847 1.1 joerg } 2848 1.1 joerg 2849 1.1 joerg /// Generates an IvarList. Used in construction of a objc_class. 2850 1.1 joerg llvm::Constant *CGObjCGNU:: 2851 1.1 joerg GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames, 2852 1.1 joerg ArrayRef<llvm::Constant *> IvarTypes, 2853 1.1 joerg ArrayRef<llvm::Constant *> IvarOffsets, 2854 1.1 joerg ArrayRef<llvm::Constant *> IvarAlign, 2855 1.1 joerg ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership) { 2856 1.1 joerg if (IvarNames.empty()) 2857 1.1 joerg return NULLPtr; 2858 1.1 joerg 2859 1.1 joerg ConstantInitBuilder Builder(CGM); 2860 1.1 joerg 2861 1.1 joerg // Structure containing array count followed by array. 2862 1.1 joerg auto IvarList = Builder.beginStruct(); 2863 1.1 joerg IvarList.addInt(IntTy, (int)IvarNames.size()); 2864 1.1 joerg 2865 1.1 joerg // Get the ivar structure type. 2866 1.1 joerg llvm::StructType *ObjCIvarTy = 2867 1.1 joerg llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy); 2868 1.1 joerg 2869 1.1 joerg // Array of ivar structures. 2870 1.1 joerg auto Ivars = IvarList.beginArray(ObjCIvarTy); 2871 1.1 joerg for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) { 2872 1.1 joerg auto Ivar = Ivars.beginStruct(ObjCIvarTy); 2873 1.1 joerg Ivar.add(IvarNames[i]); 2874 1.1 joerg Ivar.add(IvarTypes[i]); 2875 1.1 joerg Ivar.add(IvarOffsets[i]); 2876 1.1 joerg Ivar.finishAndAddTo(Ivars); 2877 1.1 joerg } 2878 1.1 joerg Ivars.finishAndAddTo(IvarList); 2879 1.1 joerg 2880 1.1 joerg // Create an instance of the structure 2881 1.1 joerg return IvarList.finishAndCreateGlobal(".objc_ivar_list", 2882 1.1 joerg CGM.getPointerAlign()); 2883 1.1 joerg } 2884 1.1 joerg 2885 1.1 joerg /// Generate a class structure 2886 1.1 joerg llvm::Constant *CGObjCGNU::GenerateClassStructure( 2887 1.1 joerg llvm::Constant *MetaClass, 2888 1.1 joerg llvm::Constant *SuperClass, 2889 1.1 joerg unsigned info, 2890 1.1 joerg const char *Name, 2891 1.1 joerg llvm::Constant *Version, 2892 1.1 joerg llvm::Constant *InstanceSize, 2893 1.1 joerg llvm::Constant *IVars, 2894 1.1 joerg llvm::Constant *Methods, 2895 1.1 joerg llvm::Constant *Protocols, 2896 1.1 joerg llvm::Constant *IvarOffsets, 2897 1.1 joerg llvm::Constant *Properties, 2898 1.1 joerg llvm::Constant *StrongIvarBitmap, 2899 1.1 joerg llvm::Constant *WeakIvarBitmap, 2900 1.1 joerg bool isMeta) { 2901 1.1 joerg // Set up the class structure 2902 1.1 joerg // Note: Several of these are char*s when they should be ids. This is 2903 1.1 joerg // because the runtime performs this translation on load. 2904 1.1 joerg // 2905 1.1 joerg // Fields marked New ABI are part of the GNUstep runtime. We emit them 2906 1.1 joerg // anyway; the classes will still work with the GNU runtime, they will just 2907 1.1 joerg // be ignored. 2908 1.1 joerg llvm::StructType *ClassTy = llvm::StructType::get( 2909 1.1 joerg PtrToInt8Ty, // isa 2910 1.1 joerg PtrToInt8Ty, // super_class 2911 1.1 joerg PtrToInt8Ty, // name 2912 1.1 joerg LongTy, // version 2913 1.1 joerg LongTy, // info 2914 1.1 joerg LongTy, // instance_size 2915 1.1 joerg IVars->getType(), // ivars 2916 1.1 joerg Methods->getType(), // methods 2917 1.1 joerg // These are all filled in by the runtime, so we pretend 2918 1.1 joerg PtrTy, // dtable 2919 1.1 joerg PtrTy, // subclass_list 2920 1.1 joerg PtrTy, // sibling_class 2921 1.1 joerg PtrTy, // protocols 2922 1.1 joerg PtrTy, // gc_object_type 2923 1.1 joerg // New ABI: 2924 1.1 joerg LongTy, // abi_version 2925 1.1 joerg IvarOffsets->getType(), // ivar_offsets 2926 1.1 joerg Properties->getType(), // properties 2927 1.1 joerg IntPtrTy, // strong_pointers 2928 1.1 joerg IntPtrTy // weak_pointers 2929 1.1 joerg ); 2930 1.1 joerg 2931 1.1 joerg ConstantInitBuilder Builder(CGM); 2932 1.1 joerg auto Elements = Builder.beginStruct(ClassTy); 2933 1.1 joerg 2934 1.1 joerg // Fill in the structure 2935 1.1 joerg 2936 1.1 joerg // isa 2937 1.1 joerg Elements.addBitCast(MetaClass, PtrToInt8Ty); 2938 1.1 joerg // super_class 2939 1.1 joerg Elements.add(SuperClass); 2940 1.1 joerg // name 2941 1.1 joerg Elements.add(MakeConstantString(Name, ".class_name")); 2942 1.1 joerg // version 2943 1.1 joerg Elements.addInt(LongTy, 0); 2944 1.1 joerg // info 2945 1.1 joerg Elements.addInt(LongTy, info); 2946 1.1 joerg // instance_size 2947 1.1 joerg if (isMeta) { 2948 1.1 joerg llvm::DataLayout td(&TheModule); 2949 1.1 joerg Elements.addInt(LongTy, 2950 1.1 joerg td.getTypeSizeInBits(ClassTy) / 2951 1.1 joerg CGM.getContext().getCharWidth()); 2952 1.1 joerg } else 2953 1.1 joerg Elements.add(InstanceSize); 2954 1.1 joerg // ivars 2955 1.1 joerg Elements.add(IVars); 2956 1.1 joerg // methods 2957 1.1 joerg Elements.add(Methods); 2958 1.1 joerg // These are all filled in by the runtime, so we pretend 2959 1.1 joerg // dtable 2960 1.1 joerg Elements.add(NULLPtr); 2961 1.1 joerg // subclass_list 2962 1.1 joerg Elements.add(NULLPtr); 2963 1.1 joerg // sibling_class 2964 1.1 joerg Elements.add(NULLPtr); 2965 1.1 joerg // protocols 2966 1.1 joerg Elements.addBitCast(Protocols, PtrTy); 2967 1.1 joerg // gc_object_type 2968 1.1 joerg Elements.add(NULLPtr); 2969 1.1 joerg // abi_version 2970 1.1 joerg Elements.addInt(LongTy, ClassABIVersion); 2971 1.1 joerg // ivar_offsets 2972 1.1 joerg Elements.add(IvarOffsets); 2973 1.1 joerg // properties 2974 1.1 joerg Elements.add(Properties); 2975 1.1 joerg // strong_pointers 2976 1.1 joerg Elements.add(StrongIvarBitmap); 2977 1.1 joerg // weak_pointers 2978 1.1 joerg Elements.add(WeakIvarBitmap); 2979 1.1 joerg // Create an instance of the structure 2980 1.1 joerg // This is now an externally visible symbol, so that we can speed up class 2981 1.1 joerg // messages in the next ABI. We may already have some weak references to 2982 1.1 joerg // this, so check and fix them properly. 2983 1.1 joerg std::string ClassSym((isMeta ? "_OBJC_METACLASS_": "_OBJC_CLASS_") + 2984 1.1 joerg std::string(Name)); 2985 1.1 joerg llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym); 2986 1.1 joerg llvm::Constant *Class = 2987 1.1 joerg Elements.finishAndCreateGlobal(ClassSym, CGM.getPointerAlign(), false, 2988 1.1 joerg llvm::GlobalValue::ExternalLinkage); 2989 1.1 joerg if (ClassRef) { 2990 1.1 joerg ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class, 2991 1.1 joerg ClassRef->getType())); 2992 1.1 joerg ClassRef->removeFromParent(); 2993 1.1 joerg Class->setName(ClassSym); 2994 1.1 joerg } 2995 1.1 joerg return Class; 2996 1.1 joerg } 2997 1.1 joerg 2998 1.1 joerg llvm::Constant *CGObjCGNU:: 2999 1.1 joerg GenerateProtocolMethodList(ArrayRef<const ObjCMethodDecl*> Methods) { 3000 1.1 joerg // Get the method structure type. 3001 1.1 joerg llvm::StructType *ObjCMethodDescTy = 3002 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty }); 3003 1.1 joerg ASTContext &Context = CGM.getContext(); 3004 1.1 joerg ConstantInitBuilder Builder(CGM); 3005 1.1 joerg auto MethodList = Builder.beginStruct(); 3006 1.1 joerg MethodList.addInt(IntTy, Methods.size()); 3007 1.1 joerg auto MethodArray = MethodList.beginArray(ObjCMethodDescTy); 3008 1.1 joerg for (auto *M : Methods) { 3009 1.1 joerg auto Method = MethodArray.beginStruct(ObjCMethodDescTy); 3010 1.1 joerg Method.add(MakeConstantString(M->getSelector().getAsString())); 3011 1.1 joerg Method.add(MakeConstantString(Context.getObjCEncodingForMethodDecl(M))); 3012 1.1 joerg Method.finishAndAddTo(MethodArray); 3013 1.1 joerg } 3014 1.1 joerg MethodArray.finishAndAddTo(MethodList); 3015 1.1 joerg return MethodList.finishAndCreateGlobal(".objc_method_list", 3016 1.1 joerg CGM.getPointerAlign()); 3017 1.1 joerg } 3018 1.1 joerg 3019 1.1 joerg // Create the protocol list structure used in classes, categories and so on 3020 1.1 joerg llvm::Constant * 3021 1.1 joerg CGObjCGNU::GenerateProtocolList(ArrayRef<std::string> Protocols) { 3022 1.1 joerg 3023 1.1 joerg ConstantInitBuilder Builder(CGM); 3024 1.1 joerg auto ProtocolList = Builder.beginStruct(); 3025 1.1 joerg ProtocolList.add(NULLPtr); 3026 1.1 joerg ProtocolList.addInt(LongTy, Protocols.size()); 3027 1.1 joerg 3028 1.1 joerg auto Elements = ProtocolList.beginArray(PtrToInt8Ty); 3029 1.1 joerg for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); 3030 1.1 joerg iter != endIter ; iter++) { 3031 1.1 joerg llvm::Constant *protocol = nullptr; 3032 1.1 joerg llvm::StringMap<llvm::Constant*>::iterator value = 3033 1.1 joerg ExistingProtocols.find(*iter); 3034 1.1 joerg if (value == ExistingProtocols.end()) { 3035 1.1 joerg protocol = GenerateEmptyProtocol(*iter); 3036 1.1 joerg } else { 3037 1.1 joerg protocol = value->getValue(); 3038 1.1 joerg } 3039 1.1 joerg Elements.addBitCast(protocol, PtrToInt8Ty); 3040 1.1 joerg } 3041 1.1 joerg Elements.finishAndAddTo(ProtocolList); 3042 1.1 joerg return ProtocolList.finishAndCreateGlobal(".objc_protocol_list", 3043 1.1 joerg CGM.getPointerAlign()); 3044 1.1 joerg } 3045 1.1 joerg 3046 1.1 joerg llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF, 3047 1.1 joerg const ObjCProtocolDecl *PD) { 3048 1.1.1.2 joerg auto protocol = GenerateProtocolRef(PD); 3049 1.1.1.2 joerg llvm::Type *T = 3050 1.1.1.2 joerg CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); 3051 1.1.1.2 joerg return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); 3052 1.1.1.2 joerg } 3053 1.1.1.2 joerg 3054 1.1.1.2 joerg llvm::Constant *CGObjCGNU::GenerateProtocolRef(const ObjCProtocolDecl *PD) { 3055 1.1 joerg llvm::Constant *&protocol = ExistingProtocols[PD->getNameAsString()]; 3056 1.1 joerg if (!protocol) 3057 1.1 joerg GenerateProtocol(PD); 3058 1.1.1.2 joerg assert(protocol && "Unknown protocol"); 3059 1.1.1.2 joerg return protocol; 3060 1.1 joerg } 3061 1.1 joerg 3062 1.1 joerg llvm::Constant * 3063 1.1 joerg CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) { 3064 1.1 joerg llvm::Constant *ProtocolList = GenerateProtocolList({}); 3065 1.1 joerg llvm::Constant *MethodList = GenerateProtocolMethodList({}); 3066 1.1 joerg MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty); 3067 1.1 joerg // Protocols are objects containing lists of the methods implemented and 3068 1.1 joerg // protocols adopted. 3069 1.1 joerg ConstantInitBuilder Builder(CGM); 3070 1.1 joerg auto Elements = Builder.beginStruct(); 3071 1.1 joerg 3072 1.1 joerg // The isa pointer must be set to a magic number so the runtime knows it's 3073 1.1 joerg // the correct layout. 3074 1.1 joerg Elements.add(llvm::ConstantExpr::getIntToPtr( 3075 1.1 joerg llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy)); 3076 1.1 joerg 3077 1.1 joerg Elements.add(MakeConstantString(ProtocolName, ".objc_protocol_name")); 3078 1.1 joerg Elements.add(ProtocolList); /* .protocol_list */ 3079 1.1 joerg Elements.add(MethodList); /* .instance_methods */ 3080 1.1 joerg Elements.add(MethodList); /* .class_methods */ 3081 1.1 joerg Elements.add(MethodList); /* .optional_instance_methods */ 3082 1.1 joerg Elements.add(MethodList); /* .optional_class_methods */ 3083 1.1 joerg Elements.add(NULLPtr); /* .properties */ 3084 1.1 joerg Elements.add(NULLPtr); /* .optional_properties */ 3085 1.1 joerg return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName), 3086 1.1 joerg CGM.getPointerAlign()); 3087 1.1 joerg } 3088 1.1 joerg 3089 1.1 joerg void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { 3090 1.1.1.2 joerg if (PD->isNonRuntimeProtocol()) 3091 1.1.1.2 joerg return; 3092 1.1.1.2 joerg 3093 1.1 joerg std::string ProtocolName = PD->getNameAsString(); 3094 1.1 joerg 3095 1.1 joerg // Use the protocol definition, if there is one. 3096 1.1 joerg if (const ObjCProtocolDecl *Def = PD->getDefinition()) 3097 1.1 joerg PD = Def; 3098 1.1 joerg 3099 1.1 joerg SmallVector<std::string, 16> Protocols; 3100 1.1 joerg for (const auto *PI : PD->protocols()) 3101 1.1 joerg Protocols.push_back(PI->getNameAsString()); 3102 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> InstanceMethods; 3103 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> OptionalInstanceMethods; 3104 1.1 joerg for (const auto *I : PD->instance_methods()) 3105 1.1 joerg if (I->isOptional()) 3106 1.1 joerg OptionalInstanceMethods.push_back(I); 3107 1.1 joerg else 3108 1.1 joerg InstanceMethods.push_back(I); 3109 1.1 joerg // Collect information about class methods: 3110 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> ClassMethods; 3111 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> OptionalClassMethods; 3112 1.1 joerg for (const auto *I : PD->class_methods()) 3113 1.1 joerg if (I->isOptional()) 3114 1.1 joerg OptionalClassMethods.push_back(I); 3115 1.1 joerg else 3116 1.1 joerg ClassMethods.push_back(I); 3117 1.1 joerg 3118 1.1 joerg llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); 3119 1.1 joerg llvm::Constant *InstanceMethodList = 3120 1.1 joerg GenerateProtocolMethodList(InstanceMethods); 3121 1.1 joerg llvm::Constant *ClassMethodList = 3122 1.1 joerg GenerateProtocolMethodList(ClassMethods); 3123 1.1 joerg llvm::Constant *OptionalInstanceMethodList = 3124 1.1 joerg GenerateProtocolMethodList(OptionalInstanceMethods); 3125 1.1 joerg llvm::Constant *OptionalClassMethodList = 3126 1.1 joerg GenerateProtocolMethodList(OptionalClassMethods); 3127 1.1 joerg 3128 1.1 joerg // Property metadata: name, attributes, isSynthesized, setter name, setter 3129 1.1 joerg // types, getter name, getter types. 3130 1.1 joerg // The isSynthesized value is always set to 0 in a protocol. It exists to 3131 1.1 joerg // simplify the runtime library by allowing it to use the same data 3132 1.1 joerg // structures for protocol metadata everywhere. 3133 1.1 joerg 3134 1.1 joerg llvm::Constant *PropertyList = 3135 1.1 joerg GeneratePropertyList(nullptr, PD, false, false); 3136 1.1 joerg llvm::Constant *OptionalPropertyList = 3137 1.1 joerg GeneratePropertyList(nullptr, PD, false, true); 3138 1.1 joerg 3139 1.1 joerg // Protocols are objects containing lists of the methods implemented and 3140 1.1 joerg // protocols adopted. 3141 1.1 joerg // The isa pointer must be set to a magic number so the runtime knows it's 3142 1.1 joerg // the correct layout. 3143 1.1 joerg ConstantInitBuilder Builder(CGM); 3144 1.1 joerg auto Elements = Builder.beginStruct(); 3145 1.1 joerg Elements.add( 3146 1.1 joerg llvm::ConstantExpr::getIntToPtr( 3147 1.1 joerg llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy)); 3148 1.1 joerg Elements.add(MakeConstantString(ProtocolName)); 3149 1.1 joerg Elements.add(ProtocolList); 3150 1.1 joerg Elements.add(InstanceMethodList); 3151 1.1 joerg Elements.add(ClassMethodList); 3152 1.1 joerg Elements.add(OptionalInstanceMethodList); 3153 1.1 joerg Elements.add(OptionalClassMethodList); 3154 1.1 joerg Elements.add(PropertyList); 3155 1.1 joerg Elements.add(OptionalPropertyList); 3156 1.1 joerg ExistingProtocols[ProtocolName] = 3157 1.1 joerg llvm::ConstantExpr::getBitCast( 3158 1.1 joerg Elements.finishAndCreateGlobal(".objc_protocol", CGM.getPointerAlign()), 3159 1.1 joerg IdTy); 3160 1.1 joerg } 3161 1.1 joerg void CGObjCGNU::GenerateProtocolHolderCategory() { 3162 1.1 joerg // Collect information about instance methods 3163 1.1 joerg 3164 1.1 joerg ConstantInitBuilder Builder(CGM); 3165 1.1 joerg auto Elements = Builder.beginStruct(); 3166 1.1 joerg 3167 1.1 joerg const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack"; 3168 1.1 joerg const std::string CategoryName = "AnotherHack"; 3169 1.1 joerg Elements.add(MakeConstantString(CategoryName)); 3170 1.1 joerg Elements.add(MakeConstantString(ClassName)); 3171 1.1 joerg // Instance method list 3172 1.1 joerg Elements.addBitCast(GenerateMethodList( 3173 1.1 joerg ClassName, CategoryName, {}, false), PtrTy); 3174 1.1 joerg // Class method list 3175 1.1 joerg Elements.addBitCast(GenerateMethodList( 3176 1.1 joerg ClassName, CategoryName, {}, true), PtrTy); 3177 1.1 joerg 3178 1.1 joerg // Protocol list 3179 1.1 joerg ConstantInitBuilder ProtocolListBuilder(CGM); 3180 1.1 joerg auto ProtocolList = ProtocolListBuilder.beginStruct(); 3181 1.1 joerg ProtocolList.add(NULLPtr); 3182 1.1 joerg ProtocolList.addInt(LongTy, ExistingProtocols.size()); 3183 1.1 joerg auto ProtocolElements = ProtocolList.beginArray(PtrTy); 3184 1.1 joerg for (auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end(); 3185 1.1 joerg iter != endIter ; iter++) { 3186 1.1 joerg ProtocolElements.addBitCast(iter->getValue(), PtrTy); 3187 1.1 joerg } 3188 1.1 joerg ProtocolElements.finishAndAddTo(ProtocolList); 3189 1.1 joerg Elements.addBitCast( 3190 1.1 joerg ProtocolList.finishAndCreateGlobal(".objc_protocol_list", 3191 1.1 joerg CGM.getPointerAlign()), 3192 1.1 joerg PtrTy); 3193 1.1 joerg Categories.push_back(llvm::ConstantExpr::getBitCast( 3194 1.1 joerg Elements.finishAndCreateGlobal("", CGM.getPointerAlign()), 3195 1.1 joerg PtrTy)); 3196 1.1 joerg } 3197 1.1 joerg 3198 1.1 joerg /// Libobjc2 uses a bitfield representation where small(ish) bitfields are 3199 1.1 joerg /// stored in a 64-bit value with the low bit set to 1 and the remaining 63 3200 1.1 joerg /// bits set to their values, LSB first, while larger ones are stored in a 3201 1.1 joerg /// structure of this / form: 3202 1.1 joerg /// 3203 1.1 joerg /// struct { int32_t length; int32_t values[length]; }; 3204 1.1 joerg /// 3205 1.1 joerg /// The values in the array are stored in host-endian format, with the least 3206 1.1 joerg /// significant bit being assumed to come first in the bitfield. Therefore, a 3207 1.1 joerg /// bitfield with the 64th bit set will be (int64_t)&{ 2, [0, 1<<31] }, while a 3208 1.1 joerg /// bitfield / with the 63rd bit set will be 1<<64. 3209 1.1 joerg llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) { 3210 1.1 joerg int bitCount = bits.size(); 3211 1.1 joerg int ptrBits = CGM.getDataLayout().getPointerSizeInBits(); 3212 1.1 joerg if (bitCount < ptrBits) { 3213 1.1 joerg uint64_t val = 1; 3214 1.1 joerg for (int i=0 ; i<bitCount ; ++i) { 3215 1.1 joerg if (bits[i]) val |= 1ULL<<(i+1); 3216 1.1 joerg } 3217 1.1 joerg return llvm::ConstantInt::get(IntPtrTy, val); 3218 1.1 joerg } 3219 1.1 joerg SmallVector<llvm::Constant *, 8> values; 3220 1.1 joerg int v=0; 3221 1.1 joerg while (v < bitCount) { 3222 1.1 joerg int32_t word = 0; 3223 1.1 joerg for (int i=0 ; (i<32) && (v<bitCount) ; ++i) { 3224 1.1 joerg if (bits[v]) word |= 1<<i; 3225 1.1 joerg v++; 3226 1.1 joerg } 3227 1.1 joerg values.push_back(llvm::ConstantInt::get(Int32Ty, word)); 3228 1.1 joerg } 3229 1.1 joerg 3230 1.1 joerg ConstantInitBuilder builder(CGM); 3231 1.1 joerg auto fields = builder.beginStruct(); 3232 1.1 joerg fields.addInt(Int32Ty, values.size()); 3233 1.1 joerg auto array = fields.beginArray(); 3234 1.1 joerg for (auto v : values) array.add(v); 3235 1.1 joerg array.finishAndAddTo(fields); 3236 1.1 joerg 3237 1.1 joerg llvm::Constant *GS = 3238 1.1 joerg fields.finishAndCreateGlobal("", CharUnits::fromQuantity(4)); 3239 1.1 joerg llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy); 3240 1.1 joerg return ptr; 3241 1.1 joerg } 3242 1.1 joerg 3243 1.1 joerg llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(const 3244 1.1 joerg ObjCCategoryDecl *OCD) { 3245 1.1.1.2 joerg const auto &RefPro = OCD->getReferencedProtocols(); 3246 1.1.1.2 joerg const auto RuntimeProtos = 3247 1.1.1.2 joerg GetRuntimeProtocolList(RefPro.begin(), RefPro.end()); 3248 1.1 joerg SmallVector<std::string, 16> Protocols; 3249 1.1.1.2 joerg for (const auto *PD : RuntimeProtos) 3250 1.1 joerg Protocols.push_back(PD->getNameAsString()); 3251 1.1 joerg return GenerateProtocolList(Protocols); 3252 1.1 joerg } 3253 1.1 joerg 3254 1.1 joerg void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 3255 1.1 joerg const ObjCInterfaceDecl *Class = OCD->getClassInterface(); 3256 1.1 joerg std::string ClassName = Class->getNameAsString(); 3257 1.1 joerg std::string CategoryName = OCD->getNameAsString(); 3258 1.1 joerg 3259 1.1 joerg // Collect the names of referenced protocols 3260 1.1 joerg const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl(); 3261 1.1 joerg 3262 1.1 joerg ConstantInitBuilder Builder(CGM); 3263 1.1 joerg auto Elements = Builder.beginStruct(); 3264 1.1 joerg Elements.add(MakeConstantString(CategoryName)); 3265 1.1 joerg Elements.add(MakeConstantString(ClassName)); 3266 1.1 joerg // Instance method list 3267 1.1 joerg SmallVector<ObjCMethodDecl*, 16> InstanceMethods; 3268 1.1 joerg InstanceMethods.insert(InstanceMethods.begin(), OCD->instmeth_begin(), 3269 1.1 joerg OCD->instmeth_end()); 3270 1.1 joerg Elements.addBitCast( 3271 1.1 joerg GenerateMethodList(ClassName, CategoryName, InstanceMethods, false), 3272 1.1 joerg PtrTy); 3273 1.1 joerg // Class method list 3274 1.1 joerg 3275 1.1 joerg SmallVector<ObjCMethodDecl*, 16> ClassMethods; 3276 1.1 joerg ClassMethods.insert(ClassMethods.begin(), OCD->classmeth_begin(), 3277 1.1 joerg OCD->classmeth_end()); 3278 1.1 joerg Elements.addBitCast( 3279 1.1 joerg GenerateMethodList(ClassName, CategoryName, ClassMethods, true), 3280 1.1 joerg PtrTy); 3281 1.1 joerg // Protocol list 3282 1.1 joerg Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy); 3283 1.1 joerg if (isRuntime(ObjCRuntime::GNUstep, 2)) { 3284 1.1 joerg const ObjCCategoryDecl *Category = 3285 1.1 joerg Class->FindCategoryDeclaration(OCD->getIdentifier()); 3286 1.1 joerg if (Category) { 3287 1.1 joerg // Instance properties 3288 1.1 joerg Elements.addBitCast(GeneratePropertyList(OCD, Category, false), PtrTy); 3289 1.1 joerg // Class properties 3290 1.1 joerg Elements.addBitCast(GeneratePropertyList(OCD, Category, true), PtrTy); 3291 1.1 joerg } else { 3292 1.1 joerg Elements.addNullPointer(PtrTy); 3293 1.1 joerg Elements.addNullPointer(PtrTy); 3294 1.1 joerg } 3295 1.1 joerg } 3296 1.1 joerg 3297 1.1 joerg Categories.push_back(llvm::ConstantExpr::getBitCast( 3298 1.1 joerg Elements.finishAndCreateGlobal( 3299 1.1 joerg std::string(".objc_category_")+ClassName+CategoryName, 3300 1.1 joerg CGM.getPointerAlign()), 3301 1.1 joerg PtrTy)); 3302 1.1 joerg } 3303 1.1 joerg 3304 1.1 joerg llvm::Constant *CGObjCGNU::GeneratePropertyList(const Decl *Container, 3305 1.1 joerg const ObjCContainerDecl *OCD, 3306 1.1 joerg bool isClassProperty, 3307 1.1 joerg bool protocolOptionalProperties) { 3308 1.1 joerg 3309 1.1 joerg SmallVector<const ObjCPropertyDecl *, 16> Properties; 3310 1.1 joerg llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; 3311 1.1 joerg bool isProtocol = isa<ObjCProtocolDecl>(OCD); 3312 1.1 joerg ASTContext &Context = CGM.getContext(); 3313 1.1 joerg 3314 1.1 joerg std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties 3315 1.1 joerg = [&](const ObjCProtocolDecl *Proto) { 3316 1.1 joerg for (const auto *P : Proto->protocols()) 3317 1.1 joerg collectProtocolProperties(P); 3318 1.1 joerg for (const auto *PD : Proto->properties()) { 3319 1.1 joerg if (isClassProperty != PD->isClassProperty()) 3320 1.1 joerg continue; 3321 1.1 joerg // Skip any properties that are declared in protocols that this class 3322 1.1 joerg // conforms to but are not actually implemented by this class. 3323 1.1 joerg if (!isProtocol && !Context.getObjCPropertyImplDeclForPropertyDecl(PD, Container)) 3324 1.1 joerg continue; 3325 1.1 joerg if (!PropertySet.insert(PD->getIdentifier()).second) 3326 1.1 joerg continue; 3327 1.1 joerg Properties.push_back(PD); 3328 1.1 joerg } 3329 1.1 joerg }; 3330 1.1 joerg 3331 1.1 joerg if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) 3332 1.1 joerg for (const ObjCCategoryDecl *ClassExt : OID->known_extensions()) 3333 1.1 joerg for (auto *PD : ClassExt->properties()) { 3334 1.1 joerg if (isClassProperty != PD->isClassProperty()) 3335 1.1 joerg continue; 3336 1.1 joerg PropertySet.insert(PD->getIdentifier()); 3337 1.1 joerg Properties.push_back(PD); 3338 1.1 joerg } 3339 1.1 joerg 3340 1.1 joerg for (const auto *PD : OCD->properties()) { 3341 1.1 joerg if (isClassProperty != PD->isClassProperty()) 3342 1.1 joerg continue; 3343 1.1 joerg // If we're generating a list for a protocol, skip optional / required ones 3344 1.1 joerg // when generating the other list. 3345 1.1 joerg if (isProtocol && (protocolOptionalProperties != PD->isOptional())) 3346 1.1 joerg continue; 3347 1.1 joerg // Don't emit duplicate metadata for properties that were already in a 3348 1.1 joerg // class extension. 3349 1.1 joerg if (!PropertySet.insert(PD->getIdentifier()).second) 3350 1.1 joerg continue; 3351 1.1 joerg 3352 1.1 joerg Properties.push_back(PD); 3353 1.1 joerg } 3354 1.1 joerg 3355 1.1 joerg if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) 3356 1.1 joerg for (const auto *P : OID->all_referenced_protocols()) 3357 1.1 joerg collectProtocolProperties(P); 3358 1.1 joerg else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) 3359 1.1 joerg for (const auto *P : CD->protocols()) 3360 1.1 joerg collectProtocolProperties(P); 3361 1.1 joerg 3362 1.1 joerg auto numProperties = Properties.size(); 3363 1.1 joerg 3364 1.1 joerg if (numProperties == 0) 3365 1.1 joerg return NULLPtr; 3366 1.1 joerg 3367 1.1 joerg ConstantInitBuilder builder(CGM); 3368 1.1 joerg auto propertyList = builder.beginStruct(); 3369 1.1 joerg auto properties = PushPropertyListHeader(propertyList, numProperties); 3370 1.1 joerg 3371 1.1 joerg // Add all of the property methods need adding to the method list and to the 3372 1.1 joerg // property metadata list. 3373 1.1 joerg for (auto *property : Properties) { 3374 1.1 joerg bool isSynthesized = false; 3375 1.1 joerg bool isDynamic = false; 3376 1.1 joerg if (!isProtocol) { 3377 1.1 joerg auto *propertyImpl = Context.getObjCPropertyImplDeclForPropertyDecl(property, Container); 3378 1.1 joerg if (propertyImpl) { 3379 1.1 joerg isSynthesized = (propertyImpl->getPropertyImplementation() == 3380 1.1 joerg ObjCPropertyImplDecl::Synthesize); 3381 1.1 joerg isDynamic = (propertyImpl->getPropertyImplementation() == 3382 1.1 joerg ObjCPropertyImplDecl::Dynamic); 3383 1.1 joerg } 3384 1.1 joerg } 3385 1.1 joerg PushProperty(properties, property, Container, isSynthesized, isDynamic); 3386 1.1 joerg } 3387 1.1 joerg properties.finishAndAddTo(propertyList); 3388 1.1 joerg 3389 1.1 joerg return propertyList.finishAndCreateGlobal(".objc_property_list", 3390 1.1 joerg CGM.getPointerAlign()); 3391 1.1 joerg } 3392 1.1 joerg 3393 1.1 joerg void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) { 3394 1.1 joerg // Get the class declaration for which the alias is specified. 3395 1.1 joerg ObjCInterfaceDecl *ClassDecl = 3396 1.1 joerg const_cast<ObjCInterfaceDecl *>(OAD->getClassInterface()); 3397 1.1 joerg ClassAliases.emplace_back(ClassDecl->getNameAsString(), 3398 1.1 joerg OAD->getNameAsString()); 3399 1.1 joerg } 3400 1.1 joerg 3401 1.1 joerg void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { 3402 1.1 joerg ASTContext &Context = CGM.getContext(); 3403 1.1 joerg 3404 1.1 joerg // Get the superclass name. 3405 1.1 joerg const ObjCInterfaceDecl * SuperClassDecl = 3406 1.1 joerg OID->getClassInterface()->getSuperClass(); 3407 1.1 joerg std::string SuperClassName; 3408 1.1 joerg if (SuperClassDecl) { 3409 1.1 joerg SuperClassName = SuperClassDecl->getNameAsString(); 3410 1.1 joerg EmitClassRef(SuperClassName); 3411 1.1 joerg } 3412 1.1 joerg 3413 1.1 joerg // Get the class name 3414 1.1 joerg ObjCInterfaceDecl *ClassDecl = 3415 1.1 joerg const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); 3416 1.1 joerg std::string ClassName = ClassDecl->getNameAsString(); 3417 1.1 joerg 3418 1.1 joerg // Emit the symbol that is used to generate linker errors if this class is 3419 1.1 joerg // referenced in other modules but not declared. 3420 1.1 joerg std::string classSymbolName = "__objc_class_name_" + ClassName; 3421 1.1 joerg if (auto *symbol = TheModule.getGlobalVariable(classSymbolName)) { 3422 1.1 joerg symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0)); 3423 1.1 joerg } else { 3424 1.1 joerg new llvm::GlobalVariable(TheModule, LongTy, false, 3425 1.1 joerg llvm::GlobalValue::ExternalLinkage, 3426 1.1 joerg llvm::ConstantInt::get(LongTy, 0), 3427 1.1 joerg classSymbolName); 3428 1.1 joerg } 3429 1.1 joerg 3430 1.1 joerg // Get the size of instances. 3431 1.1 joerg int instanceSize = 3432 1.1 joerg Context.getASTObjCImplementationLayout(OID).getSize().getQuantity(); 3433 1.1 joerg 3434 1.1 joerg // Collect information about instance variables. 3435 1.1 joerg SmallVector<llvm::Constant*, 16> IvarNames; 3436 1.1 joerg SmallVector<llvm::Constant*, 16> IvarTypes; 3437 1.1 joerg SmallVector<llvm::Constant*, 16> IvarOffsets; 3438 1.1 joerg SmallVector<llvm::Constant*, 16> IvarAligns; 3439 1.1 joerg SmallVector<Qualifiers::ObjCLifetime, 16> IvarOwnership; 3440 1.1 joerg 3441 1.1 joerg ConstantInitBuilder IvarOffsetBuilder(CGM); 3442 1.1 joerg auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy); 3443 1.1 joerg SmallVector<bool, 16> WeakIvars; 3444 1.1 joerg SmallVector<bool, 16> StrongIvars; 3445 1.1 joerg 3446 1.1 joerg int superInstanceSize = !SuperClassDecl ? 0 : 3447 1.1 joerg Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity(); 3448 1.1 joerg // For non-fragile ivars, set the instance size to 0 - {the size of just this 3449 1.1 joerg // class}. The runtime will then set this to the correct value on load. 3450 1.1 joerg if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { 3451 1.1 joerg instanceSize = 0 - (instanceSize - superInstanceSize); 3452 1.1 joerg } 3453 1.1 joerg 3454 1.1 joerg for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD; 3455 1.1 joerg IVD = IVD->getNextIvar()) { 3456 1.1 joerg // Store the name 3457 1.1 joerg IvarNames.push_back(MakeConstantString(IVD->getNameAsString())); 3458 1.1 joerg // Get the type encoding for this ivar 3459 1.1 joerg std::string TypeStr; 3460 1.1 joerg Context.getObjCEncodingForType(IVD->getType(), TypeStr, IVD); 3461 1.1 joerg IvarTypes.push_back(MakeConstantString(TypeStr)); 3462 1.1 joerg IvarAligns.push_back(llvm::ConstantInt::get(IntTy, 3463 1.1 joerg Context.getTypeSize(IVD->getType()))); 3464 1.1 joerg // Get the offset 3465 1.1 joerg uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD); 3466 1.1 joerg uint64_t Offset = BaseOffset; 3467 1.1 joerg if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { 3468 1.1 joerg Offset = BaseOffset - superInstanceSize; 3469 1.1 joerg } 3470 1.1 joerg llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset); 3471 1.1 joerg // Create the direct offset value 3472 1.1 joerg std::string OffsetName = "__objc_ivar_offset_value_" + ClassName +"." + 3473 1.1 joerg IVD->getNameAsString(); 3474 1.1 joerg 3475 1.1 joerg llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName); 3476 1.1 joerg if (OffsetVar) { 3477 1.1 joerg OffsetVar->setInitializer(OffsetValue); 3478 1.1 joerg // If this is the real definition, change its linkage type so that 3479 1.1 joerg // different modules will use this one, rather than their private 3480 1.1 joerg // copy. 3481 1.1 joerg OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage); 3482 1.1 joerg } else 3483 1.1 joerg OffsetVar = new llvm::GlobalVariable(TheModule, Int32Ty, 3484 1.1 joerg false, llvm::GlobalValue::ExternalLinkage, 3485 1.1 joerg OffsetValue, OffsetName); 3486 1.1 joerg IvarOffsets.push_back(OffsetValue); 3487 1.1 joerg IvarOffsetValues.add(OffsetVar); 3488 1.1 joerg Qualifiers::ObjCLifetime lt = IVD->getType().getQualifiers().getObjCLifetime(); 3489 1.1 joerg IvarOwnership.push_back(lt); 3490 1.1 joerg switch (lt) { 3491 1.1 joerg case Qualifiers::OCL_Strong: 3492 1.1 joerg StrongIvars.push_back(true); 3493 1.1 joerg WeakIvars.push_back(false); 3494 1.1 joerg break; 3495 1.1 joerg case Qualifiers::OCL_Weak: 3496 1.1 joerg StrongIvars.push_back(false); 3497 1.1 joerg WeakIvars.push_back(true); 3498 1.1 joerg break; 3499 1.1 joerg default: 3500 1.1 joerg StrongIvars.push_back(false); 3501 1.1 joerg WeakIvars.push_back(false); 3502 1.1 joerg } 3503 1.1 joerg } 3504 1.1 joerg llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars); 3505 1.1 joerg llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars); 3506 1.1 joerg llvm::GlobalVariable *IvarOffsetArray = 3507 1.1 joerg IvarOffsetValues.finishAndCreateGlobal(".ivar.offsets", 3508 1.1 joerg CGM.getPointerAlign()); 3509 1.1 joerg 3510 1.1 joerg // Collect information about instance methods 3511 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> InstanceMethods; 3512 1.1 joerg InstanceMethods.insert(InstanceMethods.begin(), OID->instmeth_begin(), 3513 1.1 joerg OID->instmeth_end()); 3514 1.1 joerg 3515 1.1 joerg SmallVector<const ObjCMethodDecl*, 16> ClassMethods; 3516 1.1 joerg ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(), 3517 1.1 joerg OID->classmeth_end()); 3518 1.1 joerg 3519 1.1 joerg llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl); 3520 1.1 joerg 3521 1.1 joerg // Collect the names of referenced protocols 3522 1.1.1.2 joerg auto RefProtocols = ClassDecl->protocols(); 3523 1.1.1.2 joerg auto RuntimeProtocols = 3524 1.1.1.2 joerg GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end()); 3525 1.1 joerg SmallVector<std::string, 16> Protocols; 3526 1.1.1.2 joerg for (const auto *I : RuntimeProtocols) 3527 1.1 joerg Protocols.push_back(I->getNameAsString()); 3528 1.1 joerg 3529 1.1 joerg // Get the superclass pointer. 3530 1.1 joerg llvm::Constant *SuperClass; 3531 1.1 joerg if (!SuperClassName.empty()) { 3532 1.1 joerg SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); 3533 1.1 joerg } else { 3534 1.1 joerg SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); 3535 1.1 joerg } 3536 1.1 joerg // Empty vector used to construct empty method lists 3537 1.1 joerg SmallVector<llvm::Constant*, 1> empty; 3538 1.1 joerg // Generate the method and instance variable lists 3539 1.1 joerg llvm::Constant *MethodList = GenerateMethodList(ClassName, "", 3540 1.1 joerg InstanceMethods, false); 3541 1.1 joerg llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", 3542 1.1 joerg ClassMethods, true); 3543 1.1 joerg llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, 3544 1.1 joerg IvarOffsets, IvarAligns, IvarOwnership); 3545 1.1 joerg // Irrespective of whether we are compiling for a fragile or non-fragile ABI, 3546 1.1 joerg // we emit a symbol containing the offset for each ivar in the class. This 3547 1.1 joerg // allows code compiled for the non-Fragile ABI to inherit from code compiled 3548 1.1 joerg // for the legacy ABI, without causing problems. The converse is also 3549 1.1 joerg // possible, but causes all ivar accesses to be fragile. 3550 1.1 joerg 3551 1.1 joerg // Offset pointer for getting at the correct field in the ivar list when 3552 1.1 joerg // setting up the alias. These are: The base address for the global, the 3553 1.1 joerg // ivar array (second field), the ivar in this list (set for each ivar), and 3554 1.1 joerg // the offset (third field in ivar structure) 3555 1.1 joerg llvm::Type *IndexTy = Int32Ty; 3556 1.1 joerg llvm::Constant *offsetPointerIndexes[] = {Zeros[0], 3557 1.1 joerg llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1), nullptr, 3558 1.1 joerg llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) }; 3559 1.1 joerg 3560 1.1 joerg unsigned ivarIndex = 0; 3561 1.1 joerg for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD; 3562 1.1 joerg IVD = IVD->getNextIvar()) { 3563 1.1 joerg const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD); 3564 1.1 joerg offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex); 3565 1.1 joerg // Get the correct ivar field 3566 1.1 joerg llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr( 3567 1.1 joerg cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList, 3568 1.1 joerg offsetPointerIndexes); 3569 1.1 joerg // Get the existing variable, if one exists. 3570 1.1 joerg llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name); 3571 1.1 joerg if (offset) { 3572 1.1 joerg offset->setInitializer(offsetValue); 3573 1.1 joerg // If this is the real definition, change its linkage type so that 3574 1.1 joerg // different modules will use this one, rather than their private 3575 1.1 joerg // copy. 3576 1.1 joerg offset->setLinkage(llvm::GlobalValue::ExternalLinkage); 3577 1.1 joerg } else 3578 1.1 joerg // Add a new alias if there isn't one already. 3579 1.1 joerg new llvm::GlobalVariable(TheModule, offsetValue->getType(), 3580 1.1 joerg false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name); 3581 1.1 joerg ++ivarIndex; 3582 1.1 joerg } 3583 1.1 joerg llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0); 3584 1.1 joerg 3585 1.1 joerg //Generate metaclass for class methods 3586 1.1 joerg llvm::Constant *MetaClassStruct = GenerateClassStructure( 3587 1.1 joerg NULLPtr, NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0], 3588 1.1 joerg NULLPtr, ClassMethodList, NULLPtr, NULLPtr, 3589 1.1 joerg GeneratePropertyList(OID, ClassDecl, true), ZeroPtr, ZeroPtr, true); 3590 1.1 joerg CGM.setGVProperties(cast<llvm::GlobalValue>(MetaClassStruct), 3591 1.1 joerg OID->getClassInterface()); 3592 1.1 joerg 3593 1.1 joerg // Generate the class structure 3594 1.1 joerg llvm::Constant *ClassStruct = GenerateClassStructure( 3595 1.1 joerg MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(), nullptr, 3596 1.1 joerg llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList, 3597 1.1 joerg GenerateProtocolList(Protocols), IvarOffsetArray, Properties, 3598 1.1 joerg StrongIvarBitmap, WeakIvarBitmap); 3599 1.1 joerg CGM.setGVProperties(cast<llvm::GlobalValue>(ClassStruct), 3600 1.1 joerg OID->getClassInterface()); 3601 1.1 joerg 3602 1.1 joerg // Resolve the class aliases, if they exist. 3603 1.1 joerg if (ClassPtrAlias) { 3604 1.1 joerg ClassPtrAlias->replaceAllUsesWith( 3605 1.1 joerg llvm::ConstantExpr::getBitCast(ClassStruct, IdTy)); 3606 1.1 joerg ClassPtrAlias->eraseFromParent(); 3607 1.1 joerg ClassPtrAlias = nullptr; 3608 1.1 joerg } 3609 1.1 joerg if (MetaClassPtrAlias) { 3610 1.1 joerg MetaClassPtrAlias->replaceAllUsesWith( 3611 1.1 joerg llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy)); 3612 1.1 joerg MetaClassPtrAlias->eraseFromParent(); 3613 1.1 joerg MetaClassPtrAlias = nullptr; 3614 1.1 joerg } 3615 1.1 joerg 3616 1.1 joerg // Add class structure to list to be added to the symtab later 3617 1.1 joerg ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); 3618 1.1 joerg Classes.push_back(ClassStruct); 3619 1.1 joerg } 3620 1.1 joerg 3621 1.1 joerg llvm::Function *CGObjCGNU::ModuleInitFunction() { 3622 1.1 joerg // Only emit an ObjC load function if no Objective-C stuff has been called 3623 1.1 joerg if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && 3624 1.1 joerg ExistingProtocols.empty() && SelectorTable.empty()) 3625 1.1 joerg return nullptr; 3626 1.1 joerg 3627 1.1 joerg // Add all referenced protocols to a category. 3628 1.1 joerg GenerateProtocolHolderCategory(); 3629 1.1 joerg 3630 1.1 joerg llvm::StructType *selStructTy = 3631 1.1 joerg dyn_cast<llvm::StructType>(SelectorTy->getElementType()); 3632 1.1 joerg llvm::Type *selStructPtrTy = SelectorTy; 3633 1.1 joerg if (!selStructTy) { 3634 1.1 joerg selStructTy = llvm::StructType::get(CGM.getLLVMContext(), 3635 1.1 joerg { PtrToInt8Ty, PtrToInt8Ty }); 3636 1.1 joerg selStructPtrTy = llvm::PointerType::getUnqual(selStructTy); 3637 1.1 joerg } 3638 1.1 joerg 3639 1.1 joerg // Generate statics list: 3640 1.1 joerg llvm::Constant *statics = NULLPtr; 3641 1.1 joerg if (!ConstantStrings.empty()) { 3642 1.1 joerg llvm::GlobalVariable *fileStatics = [&] { 3643 1.1 joerg ConstantInitBuilder builder(CGM); 3644 1.1 joerg auto staticsStruct = builder.beginStruct(); 3645 1.1 joerg 3646 1.1 joerg StringRef stringClass = CGM.getLangOpts().ObjCConstantStringClass; 3647 1.1 joerg if (stringClass.empty()) stringClass = "NXConstantString"; 3648 1.1 joerg staticsStruct.add(MakeConstantString(stringClass, 3649 1.1 joerg ".objc_static_class_name")); 3650 1.1 joerg 3651 1.1 joerg auto array = staticsStruct.beginArray(); 3652 1.1 joerg array.addAll(ConstantStrings); 3653 1.1 joerg array.add(NULLPtr); 3654 1.1 joerg array.finishAndAddTo(staticsStruct); 3655 1.1 joerg 3656 1.1 joerg return staticsStruct.finishAndCreateGlobal(".objc_statics", 3657 1.1 joerg CGM.getPointerAlign()); 3658 1.1 joerg }(); 3659 1.1 joerg 3660 1.1 joerg ConstantInitBuilder builder(CGM); 3661 1.1 joerg auto allStaticsArray = builder.beginArray(fileStatics->getType()); 3662 1.1 joerg allStaticsArray.add(fileStatics); 3663 1.1 joerg allStaticsArray.addNullPointer(fileStatics->getType()); 3664 1.1 joerg 3665 1.1 joerg statics = allStaticsArray.finishAndCreateGlobal(".objc_statics_ptr", 3666 1.1 joerg CGM.getPointerAlign()); 3667 1.1 joerg statics = llvm::ConstantExpr::getBitCast(statics, PtrTy); 3668 1.1 joerg } 3669 1.1 joerg 3670 1.1 joerg // Array of classes, categories, and constant objects. 3671 1.1 joerg 3672 1.1 joerg SmallVector<llvm::GlobalAlias*, 16> selectorAliases; 3673 1.1 joerg unsigned selectorCount; 3674 1.1 joerg 3675 1.1 joerg // Pointer to an array of selectors used in this module. 3676 1.1 joerg llvm::GlobalVariable *selectorList = [&] { 3677 1.1 joerg ConstantInitBuilder builder(CGM); 3678 1.1 joerg auto selectors = builder.beginArray(selStructTy); 3679 1.1 joerg auto &table = SelectorTable; // MSVC workaround 3680 1.1 joerg std::vector<Selector> allSelectors; 3681 1.1 joerg for (auto &entry : table) 3682 1.1 joerg allSelectors.push_back(entry.first); 3683 1.1 joerg llvm::sort(allSelectors); 3684 1.1 joerg 3685 1.1 joerg for (auto &untypedSel : allSelectors) { 3686 1.1 joerg std::string selNameStr = untypedSel.getAsString(); 3687 1.1 joerg llvm::Constant *selName = ExportUniqueString(selNameStr, ".objc_sel_name"); 3688 1.1 joerg 3689 1.1 joerg for (TypedSelector &sel : table[untypedSel]) { 3690 1.1 joerg llvm::Constant *selectorTypeEncoding = NULLPtr; 3691 1.1 joerg if (!sel.first.empty()) 3692 1.1 joerg selectorTypeEncoding = 3693 1.1 joerg MakeConstantString(sel.first, ".objc_sel_types"); 3694 1.1 joerg 3695 1.1 joerg auto selStruct = selectors.beginStruct(selStructTy); 3696 1.1 joerg selStruct.add(selName); 3697 1.1 joerg selStruct.add(selectorTypeEncoding); 3698 1.1 joerg selStruct.finishAndAddTo(selectors); 3699 1.1 joerg 3700 1.1 joerg // Store the selector alias for later replacement 3701 1.1 joerg selectorAliases.push_back(sel.second); 3702 1.1 joerg } 3703 1.1 joerg } 3704 1.1 joerg 3705 1.1 joerg // Remember the number of entries in the selector table. 3706 1.1 joerg selectorCount = selectors.size(); 3707 1.1 joerg 3708 1.1 joerg // NULL-terminate the selector list. This should not actually be required, 3709 1.1 joerg // because the selector list has a length field. Unfortunately, the GCC 3710 1.1 joerg // runtime decides to ignore the length field and expects a NULL terminator, 3711 1.1 joerg // and GCC cooperates with this by always setting the length to 0. 3712 1.1 joerg auto selStruct = selectors.beginStruct(selStructTy); 3713 1.1 joerg selStruct.add(NULLPtr); 3714 1.1 joerg selStruct.add(NULLPtr); 3715 1.1 joerg selStruct.finishAndAddTo(selectors); 3716 1.1 joerg 3717 1.1 joerg return selectors.finishAndCreateGlobal(".objc_selector_list", 3718 1.1 joerg CGM.getPointerAlign()); 3719 1.1 joerg }(); 3720 1.1 joerg 3721 1.1 joerg // Now that all of the static selectors exist, create pointers to them. 3722 1.1 joerg for (unsigned i = 0; i < selectorCount; ++i) { 3723 1.1 joerg llvm::Constant *idxs[] = { 3724 1.1 joerg Zeros[0], 3725 1.1 joerg llvm::ConstantInt::get(Int32Ty, i) 3726 1.1 joerg }; 3727 1.1 joerg // FIXME: We're generating redundant loads and stores here! 3728 1.1 joerg llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr( 3729 1.1 joerg selectorList->getValueType(), selectorList, idxs); 3730 1.1 joerg // If selectors are defined as an opaque type, cast the pointer to this 3731 1.1 joerg // type. 3732 1.1 joerg selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy); 3733 1.1 joerg selectorAliases[i]->replaceAllUsesWith(selPtr); 3734 1.1 joerg selectorAliases[i]->eraseFromParent(); 3735 1.1 joerg } 3736 1.1 joerg 3737 1.1 joerg llvm::GlobalVariable *symtab = [&] { 3738 1.1 joerg ConstantInitBuilder builder(CGM); 3739 1.1 joerg auto symtab = builder.beginStruct(); 3740 1.1 joerg 3741 1.1 joerg // Number of static selectors 3742 1.1 joerg symtab.addInt(LongTy, selectorCount); 3743 1.1 joerg 3744 1.1 joerg symtab.addBitCast(selectorList, selStructPtrTy); 3745 1.1 joerg 3746 1.1 joerg // Number of classes defined. 3747 1.1 joerg symtab.addInt(CGM.Int16Ty, Classes.size()); 3748 1.1 joerg // Number of categories defined 3749 1.1 joerg symtab.addInt(CGM.Int16Ty, Categories.size()); 3750 1.1 joerg 3751 1.1 joerg // Create an array of classes, then categories, then static object instances 3752 1.1 joerg auto classList = symtab.beginArray(PtrToInt8Ty); 3753 1.1 joerg classList.addAll(Classes); 3754 1.1 joerg classList.addAll(Categories); 3755 1.1 joerg // NULL-terminated list of static object instances (mainly constant strings) 3756 1.1 joerg classList.add(statics); 3757 1.1 joerg classList.add(NULLPtr); 3758 1.1 joerg classList.finishAndAddTo(symtab); 3759 1.1 joerg 3760 1.1 joerg // Construct the symbol table. 3761 1.1 joerg return symtab.finishAndCreateGlobal("", CGM.getPointerAlign()); 3762 1.1 joerg }(); 3763 1.1 joerg 3764 1.1 joerg // The symbol table is contained in a module which has some version-checking 3765 1.1 joerg // constants 3766 1.1 joerg llvm::Constant *module = [&] { 3767 1.1 joerg llvm::Type *moduleEltTys[] = { 3768 1.1 joerg LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy 3769 1.1 joerg }; 3770 1.1 joerg llvm::StructType *moduleTy = 3771 1.1 joerg llvm::StructType::get(CGM.getLLVMContext(), 3772 1.1 joerg makeArrayRef(moduleEltTys).drop_back(unsigned(RuntimeVersion < 10))); 3773 1.1 joerg 3774 1.1 joerg ConstantInitBuilder builder(CGM); 3775 1.1 joerg auto module = builder.beginStruct(moduleTy); 3776 1.1 joerg // Runtime version, used for ABI compatibility checking. 3777 1.1 joerg module.addInt(LongTy, RuntimeVersion); 3778 1.1 joerg // sizeof(ModuleTy) 3779 1.1 joerg module.addInt(LongTy, CGM.getDataLayout().getTypeStoreSize(moduleTy)); 3780 1.1 joerg 3781 1.1 joerg // The path to the source file where this module was declared 3782 1.1 joerg SourceManager &SM = CGM.getContext().getSourceManager(); 3783 1.1 joerg const FileEntry *mainFile = SM.getFileEntryForID(SM.getMainFileID()); 3784 1.1 joerg std::string path = 3785 1.1 joerg (Twine(mainFile->getDir()->getName()) + "/" + mainFile->getName()).str(); 3786 1.1 joerg module.add(MakeConstantString(path, ".objc_source_file_name")); 3787 1.1 joerg module.add(symtab); 3788 1.1 joerg 3789 1.1 joerg if (RuntimeVersion >= 10) { 3790 1.1 joerg switch (CGM.getLangOpts().getGC()) { 3791 1.1 joerg case LangOptions::GCOnly: 3792 1.1 joerg module.addInt(IntTy, 2); 3793 1.1 joerg break; 3794 1.1 joerg case LangOptions::NonGC: 3795 1.1 joerg if (CGM.getLangOpts().ObjCAutoRefCount) 3796 1.1 joerg module.addInt(IntTy, 1); 3797 1.1 joerg else 3798 1.1 joerg module.addInt(IntTy, 0); 3799 1.1 joerg break; 3800 1.1 joerg case LangOptions::HybridGC: 3801 1.1 joerg module.addInt(IntTy, 1); 3802 1.1 joerg break; 3803 1.1 joerg } 3804 1.1 joerg } 3805 1.1 joerg 3806 1.1 joerg return module.finishAndCreateGlobal("", CGM.getPointerAlign()); 3807 1.1 joerg }(); 3808 1.1 joerg 3809 1.1 joerg // Create the load function calling the runtime entry point with the module 3810 1.1 joerg // structure 3811 1.1 joerg llvm::Function * LoadFunction = llvm::Function::Create( 3812 1.1 joerg llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false), 3813 1.1 joerg llvm::GlobalValue::InternalLinkage, ".objc_load_function", 3814 1.1 joerg &TheModule); 3815 1.1 joerg llvm::BasicBlock *EntryBB = 3816 1.1 joerg llvm::BasicBlock::Create(VMContext, "entry", LoadFunction); 3817 1.1 joerg CGBuilderTy Builder(CGM, VMContext); 3818 1.1 joerg Builder.SetInsertPoint(EntryBB); 3819 1.1 joerg 3820 1.1 joerg llvm::FunctionType *FT = 3821 1.1 joerg llvm::FunctionType::get(Builder.getVoidTy(), module->getType(), true); 3822 1.1 joerg llvm::FunctionCallee Register = 3823 1.1 joerg CGM.CreateRuntimeFunction(FT, "__objc_exec_class"); 3824 1.1 joerg Builder.CreateCall(Register, module); 3825 1.1 joerg 3826 1.1 joerg if (!ClassAliases.empty()) { 3827 1.1 joerg llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty}; 3828 1.1 joerg llvm::FunctionType *RegisterAliasTy = 3829 1.1 joerg llvm::FunctionType::get(Builder.getVoidTy(), 3830 1.1 joerg ArgTypes, false); 3831 1.1 joerg llvm::Function *RegisterAlias = llvm::Function::Create( 3832 1.1 joerg RegisterAliasTy, 3833 1.1 joerg llvm::GlobalValue::ExternalWeakLinkage, "class_registerAlias_np", 3834 1.1 joerg &TheModule); 3835 1.1 joerg llvm::BasicBlock *AliasBB = 3836 1.1 joerg llvm::BasicBlock::Create(VMContext, "alias", LoadFunction); 3837 1.1 joerg llvm::BasicBlock *NoAliasBB = 3838 1.1 joerg llvm::BasicBlock::Create(VMContext, "no_alias", LoadFunction); 3839 1.1 joerg 3840 1.1 joerg // Branch based on whether the runtime provided class_registerAlias_np() 3841 1.1 joerg llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias, 3842 1.1 joerg llvm::Constant::getNullValue(RegisterAlias->getType())); 3843 1.1 joerg Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB); 3844 1.1 joerg 3845 1.1 joerg // The true branch (has alias registration function): 3846 1.1 joerg Builder.SetInsertPoint(AliasBB); 3847 1.1 joerg // Emit alias registration calls: 3848 1.1 joerg for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin(); 3849 1.1 joerg iter != ClassAliases.end(); ++iter) { 3850 1.1 joerg llvm::Constant *TheClass = 3851 1.1 joerg TheModule.getGlobalVariable("_OBJC_CLASS_" + iter->first, true); 3852 1.1 joerg if (TheClass) { 3853 1.1 joerg TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy); 3854 1.1 joerg Builder.CreateCall(RegisterAlias, 3855 1.1 joerg {TheClass, MakeConstantString(iter->second)}); 3856 1.1 joerg } 3857 1.1 joerg } 3858 1.1 joerg // Jump to end: 3859 1.1 joerg Builder.CreateBr(NoAliasBB); 3860 1.1 joerg 3861 1.1 joerg // Missing alias registration function, just return from the function: 3862 1.1 joerg Builder.SetInsertPoint(NoAliasBB); 3863 1.1 joerg } 3864 1.1 joerg Builder.CreateRetVoid(); 3865 1.1 joerg 3866 1.1 joerg return LoadFunction; 3867 1.1 joerg } 3868 1.1 joerg 3869 1.1 joerg llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, 3870 1.1 joerg const ObjCContainerDecl *CD) { 3871 1.1 joerg CodeGenTypes &Types = CGM.getTypes(); 3872 1.1 joerg llvm::FunctionType *MethodTy = 3873 1.1 joerg Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD)); 3874 1.1.1.2 joerg std::string FunctionName = getSymbolNameForMethod(OMD); 3875 1.1 joerg 3876 1.1 joerg llvm::Function *Method 3877 1.1 joerg = llvm::Function::Create(MethodTy, 3878 1.1 joerg llvm::GlobalValue::InternalLinkage, 3879 1.1 joerg FunctionName, 3880 1.1 joerg &TheModule); 3881 1.1 joerg return Method; 3882 1.1 joerg } 3883 1.1 joerg 3884 1.1.1.2 joerg void CGObjCGNU::GenerateDirectMethodPrologue(CodeGenFunction &CGF, 3885 1.1.1.2 joerg llvm::Function *Fn, 3886 1.1.1.2 joerg const ObjCMethodDecl *OMD, 3887 1.1.1.2 joerg const ObjCContainerDecl *CD) { 3888 1.1.1.2 joerg // GNU runtime doesn't support direct calls at this time 3889 1.1.1.2 joerg } 3890 1.1.1.2 joerg 3891 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() { 3892 1.1 joerg return GetPropertyFn; 3893 1.1 joerg } 3894 1.1 joerg 3895 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() { 3896 1.1 joerg return SetPropertyFn; 3897 1.1 joerg } 3898 1.1 joerg 3899 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic, 3900 1.1 joerg bool copy) { 3901 1.1 joerg return nullptr; 3902 1.1 joerg } 3903 1.1 joerg 3904 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() { 3905 1.1 joerg return GetStructPropertyFn; 3906 1.1 joerg } 3907 1.1 joerg 3908 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() { 3909 1.1 joerg return SetStructPropertyFn; 3910 1.1 joerg } 3911 1.1 joerg 3912 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() { 3913 1.1 joerg return nullptr; 3914 1.1 joerg } 3915 1.1 joerg 3916 1.1 joerg llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() { 3917 1.1 joerg return nullptr; 3918 1.1 joerg } 3919 1.1 joerg 3920 1.1 joerg llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() { 3921 1.1 joerg return EnumerationMutationFn; 3922 1.1 joerg } 3923 1.1 joerg 3924 1.1 joerg void CGObjCGNU::EmitSynchronizedStmt(CodeGenFunction &CGF, 3925 1.1 joerg const ObjCAtSynchronizedStmt &S) { 3926 1.1 joerg EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn); 3927 1.1 joerg } 3928 1.1 joerg 3929 1.1 joerg 3930 1.1 joerg void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF, 3931 1.1 joerg const ObjCAtTryStmt &S) { 3932 1.1 joerg // Unlike the Apple non-fragile runtimes, which also uses 3933 1.1 joerg // unwind-based zero cost exceptions, the GNU Objective C runtime's 3934 1.1 joerg // EH support isn't a veneer over C++ EH. Instead, exception 3935 1.1 joerg // objects are created by objc_exception_throw and destroyed by 3936 1.1 joerg // the personality function; this avoids the need for bracketing 3937 1.1 joerg // catch handlers with calls to __blah_begin_catch/__blah_end_catch 3938 1.1 joerg // (or even _Unwind_DeleteException), but probably doesn't 3939 1.1 joerg // interoperate very well with foreign exceptions. 3940 1.1 joerg // 3941 1.1 joerg // In Objective-C++ mode, we actually emit something equivalent to the C++ 3942 1.1 joerg // exception handler. 3943 1.1 joerg EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn); 3944 1.1 joerg } 3945 1.1 joerg 3946 1.1 joerg void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, 3947 1.1 joerg const ObjCAtThrowStmt &S, 3948 1.1 joerg bool ClearInsertionPoint) { 3949 1.1 joerg llvm::Value *ExceptionAsObject; 3950 1.1 joerg bool isRethrow = false; 3951 1.1 joerg 3952 1.1 joerg if (const Expr *ThrowExpr = S.getThrowExpr()) { 3953 1.1 joerg llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 3954 1.1 joerg ExceptionAsObject = Exception; 3955 1.1 joerg } else { 3956 1.1 joerg assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 3957 1.1 joerg "Unexpected rethrow outside @catch block."); 3958 1.1 joerg ExceptionAsObject = CGF.ObjCEHValueStack.back(); 3959 1.1 joerg isRethrow = true; 3960 1.1 joerg } 3961 1.1 joerg if (isRethrow && usesSEHExceptions) { 3962 1.1 joerg // For SEH, ExceptionAsObject may be undef, because the catch handler is 3963 1.1 joerg // not passed it for catchalls and so it is not visible to the catch 3964 1.1 joerg // funclet. The real thrown object will still be live on the stack at this 3965 1.1 joerg // point and will be rethrown. If we are explicitly rethrowing the object 3966 1.1 joerg // that was passed into the `@catch` block, then this code path is not 3967 1.1 joerg // reached and we will instead call `objc_exception_throw` with an explicit 3968 1.1 joerg // argument. 3969 1.1 joerg llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn); 3970 1.1 joerg Throw->setDoesNotReturn(); 3971 1.1 joerg } 3972 1.1 joerg else { 3973 1.1 joerg ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy); 3974 1.1 joerg llvm::CallBase *Throw = 3975 1.1 joerg CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject); 3976 1.1 joerg Throw->setDoesNotReturn(); 3977 1.1 joerg } 3978 1.1 joerg CGF.Builder.CreateUnreachable(); 3979 1.1 joerg if (ClearInsertionPoint) 3980 1.1 joerg CGF.Builder.ClearInsertionPoint(); 3981 1.1 joerg } 3982 1.1 joerg 3983 1.1 joerg llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF, 3984 1.1 joerg Address AddrWeakObj) { 3985 1.1 joerg CGBuilderTy &B = CGF.Builder; 3986 1.1 joerg AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy); 3987 1.1 joerg return B.CreateCall(WeakReadFn, AddrWeakObj.getPointer()); 3988 1.1 joerg } 3989 1.1 joerg 3990 1.1 joerg void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, 3991 1.1 joerg llvm::Value *src, Address dst) { 3992 1.1 joerg CGBuilderTy &B = CGF.Builder; 3993 1.1 joerg src = EnforceType(B, src, IdTy); 3994 1.1 joerg dst = EnforceType(B, dst, PtrToIdTy); 3995 1.1 joerg B.CreateCall(WeakAssignFn, {src, dst.getPointer()}); 3996 1.1 joerg } 3997 1.1 joerg 3998 1.1 joerg void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, 3999 1.1 joerg llvm::Value *src, Address dst, 4000 1.1 joerg bool threadlocal) { 4001 1.1 joerg CGBuilderTy &B = CGF.Builder; 4002 1.1 joerg src = EnforceType(B, src, IdTy); 4003 1.1 joerg dst = EnforceType(B, dst, PtrToIdTy); 4004 1.1 joerg // FIXME. Add threadloca assign API 4005 1.1 joerg assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI"); 4006 1.1 joerg B.CreateCall(GlobalAssignFn, {src, dst.getPointer()}); 4007 1.1 joerg } 4008 1.1 joerg 4009 1.1 joerg void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, 4010 1.1 joerg llvm::Value *src, Address dst, 4011 1.1 joerg llvm::Value *ivarOffset) { 4012 1.1 joerg CGBuilderTy &B = CGF.Builder; 4013 1.1 joerg src = EnforceType(B, src, IdTy); 4014 1.1 joerg dst = EnforceType(B, dst, IdTy); 4015 1.1 joerg B.CreateCall(IvarAssignFn, {src, dst.getPointer(), ivarOffset}); 4016 1.1 joerg } 4017 1.1 joerg 4018 1.1 joerg void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, 4019 1.1 joerg llvm::Value *src, Address dst) { 4020 1.1 joerg CGBuilderTy &B = CGF.Builder; 4021 1.1 joerg src = EnforceType(B, src, IdTy); 4022 1.1 joerg dst = EnforceType(B, dst, PtrToIdTy); 4023 1.1 joerg B.CreateCall(StrongCastAssignFn, {src, dst.getPointer()}); 4024 1.1 joerg } 4025 1.1 joerg 4026 1.1 joerg void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, 4027 1.1 joerg Address DestPtr, 4028 1.1 joerg Address SrcPtr, 4029 1.1 joerg llvm::Value *Size) { 4030 1.1 joerg CGBuilderTy &B = CGF.Builder; 4031 1.1 joerg DestPtr = EnforceType(B, DestPtr, PtrTy); 4032 1.1 joerg SrcPtr = EnforceType(B, SrcPtr, PtrTy); 4033 1.1 joerg 4034 1.1 joerg B.CreateCall(MemMoveFn, {DestPtr.getPointer(), SrcPtr.getPointer(), Size}); 4035 1.1 joerg } 4036 1.1 joerg 4037 1.1 joerg llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( 4038 1.1 joerg const ObjCInterfaceDecl *ID, 4039 1.1 joerg const ObjCIvarDecl *Ivar) { 4040 1.1 joerg const std::string Name = GetIVarOffsetVariableName(ID, Ivar); 4041 1.1 joerg // Emit the variable and initialize it with what we think the correct value 4042 1.1 joerg // is. This allows code compiled with non-fragile ivars to work correctly 4043 1.1 joerg // when linked against code which isn't (most of the time). 4044 1.1 joerg llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); 4045 1.1 joerg if (!IvarOffsetPointer) 4046 1.1 joerg IvarOffsetPointer = new llvm::GlobalVariable(TheModule, 4047 1.1 joerg llvm::Type::getInt32PtrTy(VMContext), false, 4048 1.1 joerg llvm::GlobalValue::ExternalLinkage, nullptr, Name); 4049 1.1 joerg return IvarOffsetPointer; 4050 1.1 joerg } 4051 1.1 joerg 4052 1.1 joerg LValue CGObjCGNU::EmitObjCValueForIvar(CodeGenFunction &CGF, 4053 1.1 joerg QualType ObjectTy, 4054 1.1 joerg llvm::Value *BaseValue, 4055 1.1 joerg const ObjCIvarDecl *Ivar, 4056 1.1 joerg unsigned CVRQualifiers) { 4057 1.1 joerg const ObjCInterfaceDecl *ID = 4058 1.1 joerg ObjectTy->castAs<ObjCObjectType>()->getInterface(); 4059 1.1 joerg return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 4060 1.1 joerg EmitIvarOffset(CGF, ID, Ivar)); 4061 1.1 joerg } 4062 1.1 joerg 4063 1.1 joerg static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 4064 1.1 joerg const ObjCInterfaceDecl *OID, 4065 1.1 joerg const ObjCIvarDecl *OIVD) { 4066 1.1 joerg for (const ObjCIvarDecl *next = OID->all_declared_ivar_begin(); next; 4067 1.1 joerg next = next->getNextIvar()) { 4068 1.1 joerg if (OIVD == next) 4069 1.1 joerg return OID; 4070 1.1 joerg } 4071 1.1 joerg 4072 1.1 joerg // Otherwise check in the super class. 4073 1.1 joerg if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 4074 1.1 joerg return FindIvarInterface(Context, Super, OIVD); 4075 1.1 joerg 4076 1.1 joerg return nullptr; 4077 1.1 joerg } 4078 1.1 joerg 4079 1.1 joerg llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF, 4080 1.1 joerg const ObjCInterfaceDecl *Interface, 4081 1.1 joerg const ObjCIvarDecl *Ivar) { 4082 1.1 joerg if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { 4083 1.1 joerg Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar); 4084 1.1 joerg 4085 1.1 joerg // The MSVC linker cannot have a single global defined as LinkOnceAnyLinkage 4086 1.1 joerg // and ExternalLinkage, so create a reference to the ivar global and rely on 4087 1.1 joerg // the definition being created as part of GenerateClass. 4088 1.1 joerg if (RuntimeVersion < 10 || 4089 1.1 joerg CGF.CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) 4090 1.1 joerg return CGF.Builder.CreateZExtOrBitCast( 4091 1.1 joerg CGF.Builder.CreateAlignedLoad( 4092 1.1 joerg Int32Ty, CGF.Builder.CreateAlignedLoad( 4093 1.1.1.2 joerg llvm::Type::getInt32PtrTy(VMContext), 4094 1.1 joerg ObjCIvarOffsetVariable(Interface, Ivar), 4095 1.1 joerg CGF.getPointerAlign(), "ivar"), 4096 1.1 joerg CharUnits::fromQuantity(4)), 4097 1.1 joerg PtrDiffTy); 4098 1.1 joerg std::string name = "__objc_ivar_offset_value_" + 4099 1.1 joerg Interface->getNameAsString() +"." + Ivar->getNameAsString(); 4100 1.1 joerg CharUnits Align = CGM.getIntAlign(); 4101 1.1 joerg llvm::Value *Offset = TheModule.getGlobalVariable(name); 4102 1.1 joerg if (!Offset) { 4103 1.1 joerg auto GV = new llvm::GlobalVariable(TheModule, IntTy, 4104 1.1 joerg false, llvm::GlobalValue::LinkOnceAnyLinkage, 4105 1.1 joerg llvm::Constant::getNullValue(IntTy), name); 4106 1.1 joerg GV->setAlignment(Align.getAsAlign()); 4107 1.1 joerg Offset = GV; 4108 1.1 joerg } 4109 1.1.1.2 joerg Offset = CGF.Builder.CreateAlignedLoad(IntTy, Offset, Align); 4110 1.1 joerg if (Offset->getType() != PtrDiffTy) 4111 1.1 joerg Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); 4112 1.1 joerg return Offset; 4113 1.1 joerg } 4114 1.1 joerg uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); 4115 1.1 joerg return llvm::ConstantInt::get(PtrDiffTy, Offset, /*isSigned*/true); 4116 1.1 joerg } 4117 1.1 joerg 4118 1.1 joerg CGObjCRuntime * 4119 1.1 joerg clang::CodeGen::CreateGNUObjCRuntime(CodeGenModule &CGM) { 4120 1.1 joerg auto Runtime = CGM.getLangOpts().ObjCRuntime; 4121 1.1 joerg switch (Runtime.getKind()) { 4122 1.1 joerg case ObjCRuntime::GNUstep: 4123 1.1 joerg if (Runtime.getVersion() >= VersionTuple(2, 0)) 4124 1.1 joerg return new CGObjCGNUstep2(CGM); 4125 1.1 joerg return new CGObjCGNUstep(CGM); 4126 1.1 joerg 4127 1.1 joerg case ObjCRuntime::GCC: 4128 1.1 joerg return new CGObjCGCC(CGM); 4129 1.1 joerg 4130 1.1 joerg case ObjCRuntime::ObjFW: 4131 1.1 joerg return new CGObjCObjFW(CGM); 4132 1.1 joerg 4133 1.1 joerg case ObjCRuntime::FragileMacOSX: 4134 1.1 joerg case ObjCRuntime::MacOSX: 4135 1.1 joerg case ObjCRuntime::iOS: 4136 1.1 joerg case ObjCRuntime::WatchOS: 4137 1.1 joerg llvm_unreachable("these runtimes are not GNU runtimes"); 4138 1.1 joerg } 4139 1.1 joerg llvm_unreachable("bad runtime"); 4140 1.1 joerg } 4141