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