1*67e74705SXin Li //===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This provides Objective-C code generation targeting the GNU runtime. The
11*67e74705SXin Li // class in this file generates structures used by the GNU Objective-C runtime
12*67e74705SXin Li // library. These structures are defined in objc/objc.h and objc/objc-api.h in
13*67e74705SXin Li // the GNU runtime distribution.
14*67e74705SXin Li //
15*67e74705SXin Li //===----------------------------------------------------------------------===//
16*67e74705SXin Li
17*67e74705SXin Li #include "CGObjCRuntime.h"
18*67e74705SXin Li #include "CGCleanup.h"
19*67e74705SXin Li #include "CodeGenFunction.h"
20*67e74705SXin Li #include "CodeGenModule.h"
21*67e74705SXin Li #include "clang/AST/ASTContext.h"
22*67e74705SXin Li #include "clang/AST/Decl.h"
23*67e74705SXin Li #include "clang/AST/DeclObjC.h"
24*67e74705SXin Li #include "clang/AST/RecordLayout.h"
25*67e74705SXin Li #include "clang/AST/StmtObjC.h"
26*67e74705SXin Li #include "clang/Basic/FileManager.h"
27*67e74705SXin Li #include "clang/Basic/SourceManager.h"
28*67e74705SXin Li #include "llvm/ADT/SmallVector.h"
29*67e74705SXin Li #include "llvm/ADT/StringMap.h"
30*67e74705SXin Li #include "llvm/IR/CallSite.h"
31*67e74705SXin Li #include "llvm/IR/DataLayout.h"
32*67e74705SXin Li #include "llvm/IR/Intrinsics.h"
33*67e74705SXin Li #include "llvm/IR/LLVMContext.h"
34*67e74705SXin Li #include "llvm/IR/Module.h"
35*67e74705SXin Li #include "llvm/Support/Compiler.h"
36*67e74705SXin Li #include <cstdarg>
37*67e74705SXin Li
38*67e74705SXin Li using namespace clang;
39*67e74705SXin Li using namespace CodeGen;
40*67e74705SXin Li
41*67e74705SXin Li namespace {
42*67e74705SXin Li /// Class that lazily initialises the runtime function. Avoids inserting the
43*67e74705SXin Li /// types and the function declaration into a module if they're not used, and
44*67e74705SXin Li /// avoids constructing the type more than once if it's used more than once.
45*67e74705SXin Li class LazyRuntimeFunction {
46*67e74705SXin Li CodeGenModule *CGM;
47*67e74705SXin Li llvm::FunctionType *FTy;
48*67e74705SXin Li const char *FunctionName;
49*67e74705SXin Li llvm::Constant *Function;
50*67e74705SXin Li
51*67e74705SXin Li public:
52*67e74705SXin Li /// Constructor leaves this class uninitialized, because it is intended to
53*67e74705SXin Li /// be used as a field in another class and not all of the types that are
54*67e74705SXin Li /// used as arguments will necessarily be available at construction time.
LazyRuntimeFunction()55*67e74705SXin Li LazyRuntimeFunction()
56*67e74705SXin Li : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
57*67e74705SXin Li
58*67e74705SXin Li /// Initialises the lazy function with the name, return type, and the types
59*67e74705SXin Li /// of the arguments.
60*67e74705SXin Li LLVM_END_WITH_NULL
init(CodeGenModule * Mod,const char * name,llvm::Type * RetTy,...)61*67e74705SXin Li void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy, ...) {
62*67e74705SXin Li CGM = Mod;
63*67e74705SXin Li FunctionName = name;
64*67e74705SXin Li Function = nullptr;
65*67e74705SXin Li std::vector<llvm::Type *> ArgTys;
66*67e74705SXin Li va_list Args;
67*67e74705SXin Li va_start(Args, RetTy);
68*67e74705SXin Li while (llvm::Type *ArgTy = va_arg(Args, llvm::Type *))
69*67e74705SXin Li ArgTys.push_back(ArgTy);
70*67e74705SXin Li va_end(Args);
71*67e74705SXin Li FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
72*67e74705SXin Li }
73*67e74705SXin Li
getType()74*67e74705SXin Li llvm::FunctionType *getType() { return FTy; }
75*67e74705SXin Li
76*67e74705SXin Li /// Overloaded cast operator, allows the class to be implicitly cast to an
77*67e74705SXin Li /// LLVM constant.
operator llvm::Constant*()78*67e74705SXin Li operator llvm::Constant *() {
79*67e74705SXin Li if (!Function) {
80*67e74705SXin Li if (!FunctionName)
81*67e74705SXin Li return nullptr;
82*67e74705SXin Li Function =
83*67e74705SXin Li cast<llvm::Constant>(CGM->CreateRuntimeFunction(FTy, FunctionName));
84*67e74705SXin Li }
85*67e74705SXin Li return Function;
86*67e74705SXin Li }
operator llvm::Function*()87*67e74705SXin Li operator llvm::Function *() {
88*67e74705SXin Li return cast<llvm::Function>((llvm::Constant *)*this);
89*67e74705SXin Li }
90*67e74705SXin Li };
91*67e74705SXin Li
92*67e74705SXin Li
93*67e74705SXin Li /// GNU Objective-C runtime code generation. This class implements the parts of
94*67e74705SXin Li /// Objective-C support that are specific to the GNU family of runtimes (GCC,
95*67e74705SXin Li /// GNUstep and ObjFW).
96*67e74705SXin Li class CGObjCGNU : public CGObjCRuntime {
97*67e74705SXin Li protected:
98*67e74705SXin Li /// The LLVM module into which output is inserted
99*67e74705SXin Li llvm::Module &TheModule;
100*67e74705SXin Li /// strut objc_super. Used for sending messages to super. This structure
101*67e74705SXin Li /// contains the receiver (object) and the expected class.
102*67e74705SXin Li llvm::StructType *ObjCSuperTy;
103*67e74705SXin Li /// struct objc_super*. The type of the argument to the superclass message
104*67e74705SXin Li /// lookup functions.
105*67e74705SXin Li llvm::PointerType *PtrToObjCSuperTy;
106*67e74705SXin Li /// LLVM type for selectors. Opaque pointer (i8*) unless a header declaring
107*67e74705SXin Li /// SEL is included in a header somewhere, in which case it will be whatever
108*67e74705SXin Li /// type is declared in that header, most likely {i8*, i8*}.
109*67e74705SXin Li llvm::PointerType *SelectorTy;
110*67e74705SXin Li /// LLVM i8 type. Cached here to avoid repeatedly getting it in all of the
111*67e74705SXin Li /// places where it's used
112*67e74705SXin Li llvm::IntegerType *Int8Ty;
113*67e74705SXin Li /// Pointer to i8 - LLVM type of char*, for all of the places where the
114*67e74705SXin Li /// runtime needs to deal with C strings.
115*67e74705SXin Li llvm::PointerType *PtrToInt8Ty;
116*67e74705SXin Li /// Instance Method Pointer type. This is a pointer to a function that takes,
117*67e74705SXin Li /// at a minimum, an object and a selector, and is the generic type for
118*67e74705SXin Li /// Objective-C methods. Due to differences between variadic / non-variadic
119*67e74705SXin Li /// calling conventions, it must always be cast to the correct type before
120*67e74705SXin Li /// actually being used.
121*67e74705SXin Li llvm::PointerType *IMPTy;
122*67e74705SXin Li /// Type of an untyped Objective-C object. Clang treats id as a built-in type
123*67e74705SXin Li /// when compiling Objective-C code, so this may be an opaque pointer (i8*),
124*67e74705SXin Li /// but if the runtime header declaring it is included then it may be a
125*67e74705SXin Li /// pointer to a structure.
126*67e74705SXin Li llvm::PointerType *IdTy;
127*67e74705SXin Li /// Pointer to a pointer to an Objective-C object. Used in the new ABI
128*67e74705SXin Li /// message lookup function and some GC-related functions.
129*67e74705SXin Li llvm::PointerType *PtrToIdTy;
130*67e74705SXin Li /// The clang type of id. Used when using the clang CGCall infrastructure to
131*67e74705SXin Li /// call Objective-C methods.
132*67e74705SXin Li CanQualType ASTIdTy;
133*67e74705SXin Li /// LLVM type for C int type.
134*67e74705SXin Li llvm::IntegerType *IntTy;
135*67e74705SXin Li /// LLVM type for an opaque pointer. This is identical to PtrToInt8Ty, but is
136*67e74705SXin Li /// used in the code to document the difference between i8* meaning a pointer
137*67e74705SXin Li /// to a C string and i8* meaning a pointer to some opaque type.
138*67e74705SXin Li llvm::PointerType *PtrTy;
139*67e74705SXin Li /// LLVM type for C long type. The runtime uses this in a lot of places where
140*67e74705SXin Li /// it should be using intptr_t, but we can't fix this without breaking
141*67e74705SXin Li /// compatibility with GCC...
142*67e74705SXin Li llvm::IntegerType *LongTy;
143*67e74705SXin Li /// LLVM type for C size_t. Used in various runtime data structures.
144*67e74705SXin Li llvm::IntegerType *SizeTy;
145*67e74705SXin Li /// LLVM type for C intptr_t.
146*67e74705SXin Li llvm::IntegerType *IntPtrTy;
147*67e74705SXin Li /// LLVM type for C ptrdiff_t. Mainly used in property accessor functions.
148*67e74705SXin Li llvm::IntegerType *PtrDiffTy;
149*67e74705SXin Li /// LLVM type for C int*. Used for GCC-ABI-compatible non-fragile instance
150*67e74705SXin Li /// variables.
151*67e74705SXin Li llvm::PointerType *PtrToIntTy;
152*67e74705SXin Li /// LLVM type for Objective-C BOOL type.
153*67e74705SXin Li llvm::Type *BoolTy;
154*67e74705SXin Li /// 32-bit integer type, to save us needing to look it up every time it's used.
155*67e74705SXin Li llvm::IntegerType *Int32Ty;
156*67e74705SXin Li /// 64-bit integer type, to save us needing to look it up every time it's used.
157*67e74705SXin Li llvm::IntegerType *Int64Ty;
158*67e74705SXin Li /// Metadata kind used to tie method lookups to message sends. The GNUstep
159*67e74705SXin Li /// runtime provides some LLVM passes that can use this to do things like
160*67e74705SXin Li /// automatic IMP caching and speculative inlining.
161*67e74705SXin Li unsigned msgSendMDKind;
162*67e74705SXin Li
163*67e74705SXin Li /// Helper function that generates a constant string and returns a pointer to
164*67e74705SXin Li /// the start of the string. The result of this function can be used anywhere
165*67e74705SXin Li /// where the C code specifies const char*.
MakeConstantString(const std::string & Str,const std::string & Name="")166*67e74705SXin Li llvm::Constant *MakeConstantString(const std::string &Str,
167*67e74705SXin Li const std::string &Name="") {
168*67e74705SXin Li ConstantAddress Array = CGM.GetAddrOfConstantCString(Str, Name.c_str());
169*67e74705SXin Li return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(),
170*67e74705SXin Li Array.getPointer(), Zeros);
171*67e74705SXin Li }
172*67e74705SXin Li
173*67e74705SXin Li /// Emits a linkonce_odr string, whose name is the prefix followed by the
174*67e74705SXin Li /// string value. This allows the linker to combine the strings between
175*67e74705SXin Li /// different modules. Used for EH typeinfo names, selector strings, and a
176*67e74705SXin Li /// few other things.
ExportUniqueString(const std::string & Str,const std::string prefix)177*67e74705SXin Li llvm::Constant *ExportUniqueString(const std::string &Str,
178*67e74705SXin Li const std::string prefix) {
179*67e74705SXin Li std::string name = prefix + Str;
180*67e74705SXin Li auto *ConstStr = TheModule.getGlobalVariable(name);
181*67e74705SXin Li if (!ConstStr) {
182*67e74705SXin Li llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
183*67e74705SXin Li ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
184*67e74705SXin Li llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
185*67e74705SXin Li }
186*67e74705SXin Li return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
187*67e74705SXin Li ConstStr, Zeros);
188*67e74705SXin Li }
189*67e74705SXin Li
190*67e74705SXin Li /// Generates a global structure, initialized by the elements in the vector.
191*67e74705SXin Li /// The element types must match the types of the structure elements in the
192*67e74705SXin Li /// first argument.
MakeGlobal(llvm::StructType * Ty,ArrayRef<llvm::Constant * > V,CharUnits Align,StringRef Name="",llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage)193*67e74705SXin Li llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,
194*67e74705SXin Li ArrayRef<llvm::Constant *> V,
195*67e74705SXin Li CharUnits Align,
196*67e74705SXin Li StringRef Name="",
197*67e74705SXin Li llvm::GlobalValue::LinkageTypes linkage
198*67e74705SXin Li =llvm::GlobalValue::InternalLinkage) {
199*67e74705SXin Li llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
200*67e74705SXin Li auto GV = new llvm::GlobalVariable(TheModule, Ty, false,
201*67e74705SXin Li linkage, C, Name);
202*67e74705SXin Li GV->setAlignment(Align.getQuantity());
203*67e74705SXin Li return GV;
204*67e74705SXin Li }
205*67e74705SXin Li
206*67e74705SXin Li /// Generates a global array. The vector must contain the same number of
207*67e74705SXin Li /// elements that the array type declares, of the type specified as the array
208*67e74705SXin Li /// element type.
MakeGlobal(llvm::ArrayType * Ty,ArrayRef<llvm::Constant * > V,CharUnits Align,StringRef Name="",llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage)209*67e74705SXin Li llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,
210*67e74705SXin Li ArrayRef<llvm::Constant *> V,
211*67e74705SXin Li CharUnits Align,
212*67e74705SXin Li StringRef Name="",
213*67e74705SXin Li llvm::GlobalValue::LinkageTypes linkage
214*67e74705SXin Li =llvm::GlobalValue::InternalLinkage) {
215*67e74705SXin Li llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
216*67e74705SXin Li auto GV = new llvm::GlobalVariable(TheModule, Ty, false,
217*67e74705SXin Li linkage, C, Name);
218*67e74705SXin Li GV->setAlignment(Align.getQuantity());
219*67e74705SXin Li return GV;
220*67e74705SXin Li }
221*67e74705SXin Li
222*67e74705SXin Li /// Generates a global array, inferring the array type from the specified
223*67e74705SXin Li /// element type and the size of the initialiser.
MakeGlobalArray(llvm::Type * Ty,ArrayRef<llvm::Constant * > V,CharUnits Align,StringRef Name="",llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage)224*67e74705SXin Li llvm::GlobalVariable *MakeGlobalArray(llvm::Type *Ty,
225*67e74705SXin Li ArrayRef<llvm::Constant *> V,
226*67e74705SXin Li CharUnits Align,
227*67e74705SXin Li StringRef Name="",
228*67e74705SXin Li llvm::GlobalValue::LinkageTypes linkage
229*67e74705SXin Li =llvm::GlobalValue::InternalLinkage) {
230*67e74705SXin Li llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
231*67e74705SXin Li return MakeGlobal(ArrayTy, V, Align, Name, linkage);
232*67e74705SXin Li }
233*67e74705SXin Li
234*67e74705SXin Li /// Returns a property name and encoding string.
MakePropertyEncodingString(const ObjCPropertyDecl * PD,const Decl * Container)235*67e74705SXin Li llvm::Constant *MakePropertyEncodingString(const ObjCPropertyDecl *PD,
236*67e74705SXin Li const Decl *Container) {
237*67e74705SXin Li const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime;
238*67e74705SXin Li if ((R.getKind() == ObjCRuntime::GNUstep) &&
239*67e74705SXin Li (R.getVersion() >= VersionTuple(1, 6))) {
240*67e74705SXin Li std::string NameAndAttributes;
241*67e74705SXin Li std::string TypeStr;
242*67e74705SXin Li CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
243*67e74705SXin Li NameAndAttributes += '\0';
244*67e74705SXin Li NameAndAttributes += TypeStr.length() + 3;
245*67e74705SXin Li NameAndAttributes += TypeStr;
246*67e74705SXin Li NameAndAttributes += '\0';
247*67e74705SXin Li NameAndAttributes += PD->getNameAsString();
248*67e74705SXin Li return MakeConstantString(NameAndAttributes);
249*67e74705SXin Li }
250*67e74705SXin Li return MakeConstantString(PD->getNameAsString());
251*67e74705SXin Li }
252*67e74705SXin Li
253*67e74705SXin Li /// Push the property attributes into two structure fields.
PushPropertyAttributes(std::vector<llvm::Constant * > & Fields,ObjCPropertyDecl * property,bool isSynthesized=true,bool isDynamic=true)254*67e74705SXin Li void PushPropertyAttributes(std::vector<llvm::Constant*> &Fields,
255*67e74705SXin Li ObjCPropertyDecl *property, bool isSynthesized=true, bool
256*67e74705SXin Li isDynamic=true) {
257*67e74705SXin Li int attrs = property->getPropertyAttributes();
258*67e74705SXin Li // For read-only properties, clear the copy and retain flags
259*67e74705SXin Li if (attrs & ObjCPropertyDecl::OBJC_PR_readonly) {
260*67e74705SXin Li attrs &= ~ObjCPropertyDecl::OBJC_PR_copy;
261*67e74705SXin Li attrs &= ~ObjCPropertyDecl::OBJC_PR_retain;
262*67e74705SXin Li attrs &= ~ObjCPropertyDecl::OBJC_PR_weak;
263*67e74705SXin Li attrs &= ~ObjCPropertyDecl::OBJC_PR_strong;
264*67e74705SXin Li }
265*67e74705SXin Li // The first flags field has the same attribute values as clang uses internally
266*67e74705SXin Li Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
267*67e74705SXin Li attrs >>= 8;
268*67e74705SXin Li attrs <<= 2;
269*67e74705SXin Li // For protocol properties, synthesized and dynamic have no meaning, so we
270*67e74705SXin Li // reuse these flags to indicate that this is a protocol property (both set
271*67e74705SXin Li // has no meaning, as a property can't be both synthesized and dynamic)
272*67e74705SXin Li attrs |= isSynthesized ? (1<<0) : 0;
273*67e74705SXin Li attrs |= isDynamic ? (1<<1) : 0;
274*67e74705SXin Li // The second field is the next four fields left shifted by two, with the
275*67e74705SXin Li // low bit set to indicate whether the field is synthesized or dynamic.
276*67e74705SXin Li Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
277*67e74705SXin Li // Two padding fields
278*67e74705SXin Li Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
279*67e74705SXin Li Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
280*67e74705SXin Li }
281*67e74705SXin Li
282*67e74705SXin Li /// Ensures that the value has the required type, by inserting a bitcast if
283*67e74705SXin Li /// required. This function lets us avoid inserting bitcasts that are
284*67e74705SXin Li /// redundant.
EnforceType(CGBuilderTy & B,llvm::Value * V,llvm::Type * Ty)285*67e74705SXin Li llvm::Value* EnforceType(CGBuilderTy &B, llvm::Value *V, llvm::Type *Ty) {
286*67e74705SXin Li if (V->getType() == Ty) return V;
287*67e74705SXin Li return B.CreateBitCast(V, Ty);
288*67e74705SXin Li }
EnforceType(CGBuilderTy & B,Address V,llvm::Type * Ty)289*67e74705SXin Li Address EnforceType(CGBuilderTy &B, Address V, llvm::Type *Ty) {
290*67e74705SXin Li if (V.getType() == Ty) return V;
291*67e74705SXin Li return B.CreateBitCast(V, Ty);
292*67e74705SXin Li }
293*67e74705SXin Li
294*67e74705SXin Li // Some zeros used for GEPs in lots of places.
295*67e74705SXin Li llvm::Constant *Zeros[2];
296*67e74705SXin Li /// Null pointer value. Mainly used as a terminator in various arrays.
297*67e74705SXin Li llvm::Constant *NULLPtr;
298*67e74705SXin Li /// LLVM context.
299*67e74705SXin Li llvm::LLVMContext &VMContext;
300*67e74705SXin Li
301*67e74705SXin Li private:
302*67e74705SXin Li /// Placeholder for the class. Lots of things refer to the class before we've
303*67e74705SXin Li /// actually emitted it. We use this alias as a placeholder, and then replace
304*67e74705SXin Li /// it with a pointer to the class structure before finally emitting the
305*67e74705SXin Li /// module.
306*67e74705SXin Li llvm::GlobalAlias *ClassPtrAlias;
307*67e74705SXin Li /// Placeholder for the metaclass. Lots of things refer to the class before
308*67e74705SXin Li /// we've / actually emitted it. We use this alias as a placeholder, and then
309*67e74705SXin Li /// replace / it with a pointer to the metaclass structure before finally
310*67e74705SXin Li /// emitting the / module.
311*67e74705SXin Li llvm::GlobalAlias *MetaClassPtrAlias;
312*67e74705SXin Li /// All of the classes that have been generated for this compilation units.
313*67e74705SXin Li std::vector<llvm::Constant*> Classes;
314*67e74705SXin Li /// All of the categories that have been generated for this compilation units.
315*67e74705SXin Li std::vector<llvm::Constant*> Categories;
316*67e74705SXin Li /// All of the Objective-C constant strings that have been generated for this
317*67e74705SXin Li /// compilation units.
318*67e74705SXin Li std::vector<llvm::Constant*> ConstantStrings;
319*67e74705SXin Li /// Map from string values to Objective-C constant strings in the output.
320*67e74705SXin Li /// Used to prevent emitting Objective-C strings more than once. This should
321*67e74705SXin Li /// not be required at all - CodeGenModule should manage this list.
322*67e74705SXin Li llvm::StringMap<llvm::Constant*> ObjCStrings;
323*67e74705SXin Li /// All of the protocols that have been declared.
324*67e74705SXin Li llvm::StringMap<llvm::Constant*> ExistingProtocols;
325*67e74705SXin Li /// For each variant of a selector, we store the type encoding and a
326*67e74705SXin Li /// placeholder value. For an untyped selector, the type will be the empty
327*67e74705SXin Li /// string. Selector references are all done via the module's selector table,
328*67e74705SXin Li /// so we create an alias as a placeholder and then replace it with the real
329*67e74705SXin Li /// value later.
330*67e74705SXin Li typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
331*67e74705SXin Li /// Type of the selector map. This is roughly equivalent to the structure
332*67e74705SXin Li /// used in the GNUstep runtime, which maintains a list of all of the valid
333*67e74705SXin Li /// types for a selector in a table.
334*67e74705SXin Li typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
335*67e74705SXin Li SelectorMap;
336*67e74705SXin Li /// A map from selectors to selector types. This allows us to emit all
337*67e74705SXin Li /// selectors of the same name and type together.
338*67e74705SXin Li SelectorMap SelectorTable;
339*67e74705SXin Li
340*67e74705SXin Li /// Selectors related to memory management. When compiling in GC mode, we
341*67e74705SXin Li /// omit these.
342*67e74705SXin Li Selector RetainSel, ReleaseSel, AutoreleaseSel;
343*67e74705SXin Li /// Runtime functions used for memory management in GC mode. Note that clang
344*67e74705SXin Li /// supports code generation for calling these functions, but neither GNU
345*67e74705SXin Li /// runtime actually supports this API properly yet.
346*67e74705SXin Li LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
347*67e74705SXin Li WeakAssignFn, GlobalAssignFn;
348*67e74705SXin Li
349*67e74705SXin Li typedef std::pair<std::string, std::string> ClassAliasPair;
350*67e74705SXin Li /// All classes that have aliases set for them.
351*67e74705SXin Li std::vector<ClassAliasPair> ClassAliases;
352*67e74705SXin Li
353*67e74705SXin Li protected:
354*67e74705SXin Li /// Function used for throwing Objective-C exceptions.
355*67e74705SXin Li LazyRuntimeFunction ExceptionThrowFn;
356*67e74705SXin Li /// Function used for rethrowing exceptions, used at the end of \@finally or
357*67e74705SXin Li /// \@synchronize blocks.
358*67e74705SXin Li LazyRuntimeFunction ExceptionReThrowFn;
359*67e74705SXin Li /// Function called when entering a catch function. This is required for
360*67e74705SXin Li /// differentiating Objective-C exceptions and foreign exceptions.
361*67e74705SXin Li LazyRuntimeFunction EnterCatchFn;
362*67e74705SXin Li /// Function called when exiting from a catch block. Used to do exception
363*67e74705SXin Li /// cleanup.
364*67e74705SXin Li LazyRuntimeFunction ExitCatchFn;
365*67e74705SXin Li /// Function called when entering an \@synchronize block. Acquires the lock.
366*67e74705SXin Li LazyRuntimeFunction SyncEnterFn;
367*67e74705SXin Li /// Function called when exiting an \@synchronize block. Releases the lock.
368*67e74705SXin Li LazyRuntimeFunction SyncExitFn;
369*67e74705SXin Li
370*67e74705SXin Li private:
371*67e74705SXin Li /// Function called if fast enumeration detects that the collection is
372*67e74705SXin Li /// modified during the update.
373*67e74705SXin Li LazyRuntimeFunction EnumerationMutationFn;
374*67e74705SXin Li /// Function for implementing synthesized property getters that return an
375*67e74705SXin Li /// object.
376*67e74705SXin Li LazyRuntimeFunction GetPropertyFn;
377*67e74705SXin Li /// Function for implementing synthesized property setters that return an
378*67e74705SXin Li /// object.
379*67e74705SXin Li LazyRuntimeFunction SetPropertyFn;
380*67e74705SXin Li /// Function used for non-object declared property getters.
381*67e74705SXin Li LazyRuntimeFunction GetStructPropertyFn;
382*67e74705SXin Li /// Function used for non-object declared property setters.
383*67e74705SXin Li LazyRuntimeFunction SetStructPropertyFn;
384*67e74705SXin Li
385*67e74705SXin Li /// The version of the runtime that this class targets. Must match the
386*67e74705SXin Li /// version in the runtime.
387*67e74705SXin Li int RuntimeVersion;
388*67e74705SXin Li /// The version of the protocol class. Used to differentiate between ObjC1
389*67e74705SXin Li /// and ObjC2 protocols. Objective-C 1 protocols can not contain optional
390*67e74705SXin Li /// components and can not contain declared properties. We always emit
391*67e74705SXin Li /// Objective-C 2 property structures, but we have to pretend that they're
392*67e74705SXin Li /// Objective-C 1 property structures when targeting the GCC runtime or it
393*67e74705SXin Li /// will abort.
394*67e74705SXin Li const int ProtocolVersion;
395*67e74705SXin Li
396*67e74705SXin Li /// Generates an instance variable list structure. This is a structure
397*67e74705SXin Li /// containing a size and an array of structures containing instance variable
398*67e74705SXin Li /// metadata. This is used purely for introspection in the fragile ABI. In
399*67e74705SXin Li /// the non-fragile ABI, it's used for instance variable fixup.
400*67e74705SXin Li llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
401*67e74705SXin Li ArrayRef<llvm::Constant *> IvarTypes,
402*67e74705SXin Li ArrayRef<llvm::Constant *> IvarOffsets);
403*67e74705SXin Li
404*67e74705SXin Li /// Generates a method list structure. This is a structure containing a size
405*67e74705SXin Li /// and an array of structures containing method metadata.
406*67e74705SXin Li ///
407*67e74705SXin Li /// This structure is used by both classes and categories, and contains a next
408*67e74705SXin Li /// pointer allowing them to be chained together in a linked list.
409*67e74705SXin Li llvm::Constant *GenerateMethodList(StringRef ClassName,
410*67e74705SXin Li StringRef CategoryName,
411*67e74705SXin Li ArrayRef<Selector> MethodSels,
412*67e74705SXin Li ArrayRef<llvm::Constant *> MethodTypes,
413*67e74705SXin Li bool isClassMethodList);
414*67e74705SXin Li
415*67e74705SXin Li /// Emits an empty protocol. This is used for \@protocol() where no protocol
416*67e74705SXin Li /// is found. The runtime will (hopefully) fix up the pointer to refer to the
417*67e74705SXin Li /// real protocol.
418*67e74705SXin Li llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
419*67e74705SXin Li
420*67e74705SXin Li /// Generates a list of property metadata structures. This follows the same
421*67e74705SXin Li /// pattern as method and instance variable metadata lists.
422*67e74705SXin Li llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID,
423*67e74705SXin Li SmallVectorImpl<Selector> &InstanceMethodSels,
424*67e74705SXin Li SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes);
425*67e74705SXin Li
426*67e74705SXin Li /// Generates a list of referenced protocols. Classes, categories, and
427*67e74705SXin Li /// protocols all use this structure.
428*67e74705SXin Li llvm::Constant *GenerateProtocolList(ArrayRef<std::string> Protocols);
429*67e74705SXin Li
430*67e74705SXin Li /// To ensure that all protocols are seen by the runtime, we add a category on
431*67e74705SXin Li /// a class defined in the runtime, declaring no methods, but adopting the
432*67e74705SXin Li /// protocols. This is a horribly ugly hack, but it allows us to collect all
433*67e74705SXin Li /// of the protocols without changing the ABI.
434*67e74705SXin Li void GenerateProtocolHolderCategory();
435*67e74705SXin Li
436*67e74705SXin Li /// Generates a class structure.
437*67e74705SXin Li llvm::Constant *GenerateClassStructure(
438*67e74705SXin Li llvm::Constant *MetaClass,
439*67e74705SXin Li llvm::Constant *SuperClass,
440*67e74705SXin Li unsigned info,
441*67e74705SXin Li const char *Name,
442*67e74705SXin Li llvm::Constant *Version,
443*67e74705SXin Li llvm::Constant *InstanceSize,
444*67e74705SXin Li llvm::Constant *IVars,
445*67e74705SXin Li llvm::Constant *Methods,
446*67e74705SXin Li llvm::Constant *Protocols,
447*67e74705SXin Li llvm::Constant *IvarOffsets,
448*67e74705SXin Li llvm::Constant *Properties,
449*67e74705SXin Li llvm::Constant *StrongIvarBitmap,
450*67e74705SXin Li llvm::Constant *WeakIvarBitmap,
451*67e74705SXin Li bool isMeta=false);
452*67e74705SXin Li
453*67e74705SXin Li /// Generates a method list. This is used by protocols to define the required
454*67e74705SXin Li /// and optional methods.
455*67e74705SXin Li llvm::Constant *GenerateProtocolMethodList(
456*67e74705SXin Li ArrayRef<llvm::Constant *> MethodNames,
457*67e74705SXin Li ArrayRef<llvm::Constant *> MethodTypes);
458*67e74705SXin Li
459*67e74705SXin Li /// Returns a selector with the specified type encoding. An empty string is
460*67e74705SXin Li /// used to return an untyped selector (with the types field set to NULL).
461*67e74705SXin Li llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
462*67e74705SXin Li const std::string &TypeEncoding);
463*67e74705SXin Li
464*67e74705SXin Li /// Returns the variable used to store the offset of an instance variable.
465*67e74705SXin Li llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
466*67e74705SXin Li const ObjCIvarDecl *Ivar);
467*67e74705SXin Li /// Emits a reference to a class. This allows the linker to object if there
468*67e74705SXin Li /// is no class of the matching name.
469*67e74705SXin Li
470*67e74705SXin Li protected:
471*67e74705SXin Li void EmitClassRef(const std::string &className);
472*67e74705SXin Li
473*67e74705SXin Li /// Emits a pointer to the named class
474*67e74705SXin Li virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF,
475*67e74705SXin Li const std::string &Name, bool isWeak);
476*67e74705SXin Li
477*67e74705SXin Li /// Looks up the method for sending a message to the specified object. This
478*67e74705SXin Li /// mechanism differs between the GCC and GNU runtimes, so this method must be
479*67e74705SXin Li /// overridden in subclasses.
480*67e74705SXin Li virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
481*67e74705SXin Li llvm::Value *&Receiver,
482*67e74705SXin Li llvm::Value *cmd,
483*67e74705SXin Li llvm::MDNode *node,
484*67e74705SXin Li MessageSendInfo &MSI) = 0;
485*67e74705SXin Li
486*67e74705SXin Li /// Looks up the method for sending a message to a superclass. This
487*67e74705SXin Li /// mechanism differs between the GCC and GNU runtimes, so this method must
488*67e74705SXin Li /// be overridden in subclasses.
489*67e74705SXin Li virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
490*67e74705SXin Li Address ObjCSuper,
491*67e74705SXin Li llvm::Value *cmd,
492*67e74705SXin Li MessageSendInfo &MSI) = 0;
493*67e74705SXin Li
494*67e74705SXin Li /// Libobjc2 uses a bitfield representation where small(ish) bitfields are
495*67e74705SXin Li /// stored in a 64-bit value with the low bit set to 1 and the remaining 63
496*67e74705SXin Li /// bits set to their values, LSB first, while larger ones are stored in a
497*67e74705SXin Li /// structure of this / form:
498*67e74705SXin Li ///
499*67e74705SXin Li /// struct { int32_t length; int32_t values[length]; };
500*67e74705SXin Li ///
501*67e74705SXin Li /// The values in the array are stored in host-endian format, with the least
502*67e74705SXin Li /// significant bit being assumed to come first in the bitfield. Therefore,
503*67e74705SXin Li /// a bitfield with the 64th bit set will be (int64_t)&{ 2, [0, 1<<31] },
504*67e74705SXin Li /// while a bitfield / with the 63rd bit set will be 1<<64.
505*67e74705SXin Li llvm::Constant *MakeBitField(ArrayRef<bool> bits);
506*67e74705SXin Li
507*67e74705SXin Li public:
508*67e74705SXin Li CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
509*67e74705SXin Li unsigned protocolClassVersion);
510*67e74705SXin Li
511*67e74705SXin Li ConstantAddress GenerateConstantString(const StringLiteral *) override;
512*67e74705SXin Li
513*67e74705SXin Li RValue
514*67e74705SXin Li GenerateMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return,
515*67e74705SXin Li QualType ResultType, Selector Sel,
516*67e74705SXin Li llvm::Value *Receiver, const CallArgList &CallArgs,
517*67e74705SXin Li const ObjCInterfaceDecl *Class,
518*67e74705SXin Li const ObjCMethodDecl *Method) override;
519*67e74705SXin Li RValue
520*67e74705SXin Li GenerateMessageSendSuper(CodeGenFunction &CGF, ReturnValueSlot Return,
521*67e74705SXin Li QualType ResultType, Selector Sel,
522*67e74705SXin Li const ObjCInterfaceDecl *Class,
523*67e74705SXin Li bool isCategoryImpl, llvm::Value *Receiver,
524*67e74705SXin Li bool IsClassMessage, const CallArgList &CallArgs,
525*67e74705SXin Li const ObjCMethodDecl *Method) override;
526*67e74705SXin Li llvm::Value *GetClass(CodeGenFunction &CGF,
527*67e74705SXin Li const ObjCInterfaceDecl *OID) override;
528*67e74705SXin Li llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override;
529*67e74705SXin Li Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;
530*67e74705SXin Li llvm::Value *GetSelector(CodeGenFunction &CGF,
531*67e74705SXin Li const ObjCMethodDecl *Method) override;
532*67e74705SXin Li llvm::Constant *GetEHType(QualType T) override;
533*67e74705SXin Li
534*67e74705SXin Li llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
535*67e74705SXin Li const ObjCContainerDecl *CD) override;
536*67e74705SXin Li void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
537*67e74705SXin Li void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
538*67e74705SXin Li void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override;
539*67e74705SXin Li llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
540*67e74705SXin Li const ObjCProtocolDecl *PD) override;
541*67e74705SXin Li void GenerateProtocol(const ObjCProtocolDecl *PD) override;
542*67e74705SXin Li llvm::Function *ModuleInitFunction() override;
543*67e74705SXin Li llvm::Constant *GetPropertyGetFunction() override;
544*67e74705SXin Li llvm::Constant *GetPropertySetFunction() override;
545*67e74705SXin Li llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
546*67e74705SXin Li bool copy) override;
547*67e74705SXin Li llvm::Constant *GetSetStructFunction() override;
548*67e74705SXin Li llvm::Constant *GetGetStructFunction() override;
549*67e74705SXin Li llvm::Constant *GetCppAtomicObjectGetFunction() override;
550*67e74705SXin Li llvm::Constant *GetCppAtomicObjectSetFunction() override;
551*67e74705SXin Li llvm::Constant *EnumerationMutationFunction() override;
552*67e74705SXin Li
553*67e74705SXin Li void EmitTryStmt(CodeGenFunction &CGF,
554*67e74705SXin Li const ObjCAtTryStmt &S) override;
555*67e74705SXin Li void EmitSynchronizedStmt(CodeGenFunction &CGF,
556*67e74705SXin Li const ObjCAtSynchronizedStmt &S) override;
557*67e74705SXin Li void EmitThrowStmt(CodeGenFunction &CGF,
558*67e74705SXin Li const ObjCAtThrowStmt &S,
559*67e74705SXin Li bool ClearInsertionPoint=true) override;
560*67e74705SXin Li llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF,
561*67e74705SXin Li Address AddrWeakObj) override;
562*67e74705SXin Li void EmitObjCWeakAssign(CodeGenFunction &CGF,
563*67e74705SXin Li llvm::Value *src, Address dst) override;
564*67e74705SXin Li void EmitObjCGlobalAssign(CodeGenFunction &CGF,
565*67e74705SXin Li llvm::Value *src, Address dest,
566*67e74705SXin Li bool threadlocal=false) override;
567*67e74705SXin Li void EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *src,
568*67e74705SXin Li Address dest, llvm::Value *ivarOffset) override;
569*67e74705SXin Li void EmitObjCStrongCastAssign(CodeGenFunction &CGF,
570*67e74705SXin Li llvm::Value *src, Address dest) override;
571*67e74705SXin Li void EmitGCMemmoveCollectable(CodeGenFunction &CGF, Address DestPtr,
572*67e74705SXin Li Address SrcPtr,
573*67e74705SXin Li llvm::Value *Size) override;
574*67e74705SXin Li LValue EmitObjCValueForIvar(CodeGenFunction &CGF, QualType ObjectTy,
575*67e74705SXin Li llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
576*67e74705SXin Li unsigned CVRQualifiers) override;
577*67e74705SXin Li llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
578*67e74705SXin Li const ObjCInterfaceDecl *Interface,
579*67e74705SXin Li const ObjCIvarDecl *Ivar) override;
580*67e74705SXin Li llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
BuildGCBlockLayout(CodeGenModule & CGM,const CGBlockInfo & blockInfo)581*67e74705SXin Li llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM,
582*67e74705SXin Li const CGBlockInfo &blockInfo) override {
583*67e74705SXin Li return NULLPtr;
584*67e74705SXin Li }
BuildRCBlockLayout(CodeGenModule & CGM,const CGBlockInfo & blockInfo)585*67e74705SXin Li llvm::Constant *BuildRCBlockLayout(CodeGenModule &CGM,
586*67e74705SXin Li const CGBlockInfo &blockInfo) override {
587*67e74705SXin Li return NULLPtr;
588*67e74705SXin Li }
589*67e74705SXin Li
BuildByrefLayout(CodeGenModule & CGM,QualType T)590*67e74705SXin Li llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, QualType T) override {
591*67e74705SXin Li return NULLPtr;
592*67e74705SXin Li }
593*67e74705SXin Li
GetClassGlobal(StringRef Name,bool Weak=false)594*67e74705SXin Li llvm::GlobalVariable *GetClassGlobal(StringRef Name,
595*67e74705SXin Li bool Weak = false) override {
596*67e74705SXin Li return nullptr;
597*67e74705SXin Li }
598*67e74705SXin Li };
599*67e74705SXin Li
600*67e74705SXin Li /// Class representing the legacy GCC Objective-C ABI. This is the default when
601*67e74705SXin Li /// -fobjc-nonfragile-abi is not specified.
602*67e74705SXin Li ///
603*67e74705SXin Li /// The GCC ABI target actually generates code that is approximately compatible
604*67e74705SXin Li /// with the new GNUstep runtime ABI, but refrains from using any features that
605*67e74705SXin Li /// would not work with the GCC runtime. For example, clang always generates
606*67e74705SXin Li /// the extended form of the class structure, and the extra fields are simply
607*67e74705SXin Li /// ignored by GCC libobjc.
608*67e74705SXin Li class CGObjCGCC : public CGObjCGNU {
609*67e74705SXin Li /// The GCC ABI message lookup function. Returns an IMP pointing to the
610*67e74705SXin Li /// method implementation for this message.
611*67e74705SXin Li LazyRuntimeFunction MsgLookupFn;
612*67e74705SXin Li /// The GCC ABI superclass message lookup function. Takes a pointer to a
613*67e74705SXin Li /// structure describing the receiver and the class, and a selector as
614*67e74705SXin Li /// arguments. Returns the IMP for the corresponding method.
615*67e74705SXin Li LazyRuntimeFunction MsgLookupSuperFn;
616*67e74705SXin Li
617*67e74705SXin Li protected:
LookupIMP(CodeGenFunction & CGF,llvm::Value * & Receiver,llvm::Value * cmd,llvm::MDNode * node,MessageSendInfo & MSI)618*67e74705SXin Li llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
619*67e74705SXin Li llvm::Value *cmd, llvm::MDNode *node,
620*67e74705SXin Li MessageSendInfo &MSI) override {
621*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
622*67e74705SXin Li llvm::Value *args[] = {
623*67e74705SXin Li EnforceType(Builder, Receiver, IdTy),
624*67e74705SXin Li EnforceType(Builder, cmd, SelectorTy) };
625*67e74705SXin Li llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
626*67e74705SXin Li imp->setMetadata(msgSendMDKind, node);
627*67e74705SXin Li return imp.getInstruction();
628*67e74705SXin Li }
629*67e74705SXin Li
LookupIMPSuper(CodeGenFunction & CGF,Address ObjCSuper,llvm::Value * cmd,MessageSendInfo & MSI)630*67e74705SXin Li llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
631*67e74705SXin Li llvm::Value *cmd, MessageSendInfo &MSI) override {
632*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
633*67e74705SXin Li llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
634*67e74705SXin Li PtrToObjCSuperTy).getPointer(), cmd};
635*67e74705SXin Li return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs);
636*67e74705SXin Li }
637*67e74705SXin Li
638*67e74705SXin Li public:
CGObjCGCC(CodeGenModule & Mod)639*67e74705SXin Li CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) {
640*67e74705SXin Li // IMP objc_msg_lookup(id, SEL);
641*67e74705SXin Li MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy,
642*67e74705SXin Li nullptr);
643*67e74705SXin Li // IMP objc_msg_lookup_super(struct objc_super*, SEL);
644*67e74705SXin Li MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
645*67e74705SXin Li PtrToObjCSuperTy, SelectorTy, nullptr);
646*67e74705SXin Li }
647*67e74705SXin Li };
648*67e74705SXin Li
649*67e74705SXin Li /// Class used when targeting the new GNUstep runtime ABI.
650*67e74705SXin Li class CGObjCGNUstep : public CGObjCGNU {
651*67e74705SXin Li /// The slot lookup function. Returns a pointer to a cacheable structure
652*67e74705SXin Li /// that contains (among other things) the IMP.
653*67e74705SXin Li LazyRuntimeFunction SlotLookupFn;
654*67e74705SXin Li /// The GNUstep ABI superclass message lookup function. Takes a pointer to
655*67e74705SXin Li /// a structure describing the receiver and the class, and a selector as
656*67e74705SXin Li /// arguments. Returns the slot for the corresponding method. Superclass
657*67e74705SXin Li /// message lookup rarely changes, so this is a good caching opportunity.
658*67e74705SXin Li LazyRuntimeFunction SlotLookupSuperFn;
659*67e74705SXin Li /// Specialised function for setting atomic retain properties
660*67e74705SXin Li LazyRuntimeFunction SetPropertyAtomic;
661*67e74705SXin Li /// Specialised function for setting atomic copy properties
662*67e74705SXin Li LazyRuntimeFunction SetPropertyAtomicCopy;
663*67e74705SXin Li /// Specialised function for setting nonatomic retain properties
664*67e74705SXin Li LazyRuntimeFunction SetPropertyNonAtomic;
665*67e74705SXin Li /// Specialised function for setting nonatomic copy properties
666*67e74705SXin Li LazyRuntimeFunction SetPropertyNonAtomicCopy;
667*67e74705SXin Li /// Function to perform atomic copies of C++ objects with nontrivial copy
668*67e74705SXin Li /// constructors from Objective-C ivars.
669*67e74705SXin Li LazyRuntimeFunction CxxAtomicObjectGetFn;
670*67e74705SXin Li /// Function to perform atomic copies of C++ objects with nontrivial copy
671*67e74705SXin Li /// constructors to Objective-C ivars.
672*67e74705SXin Li LazyRuntimeFunction CxxAtomicObjectSetFn;
673*67e74705SXin Li /// Type of an slot structure pointer. This is returned by the various
674*67e74705SXin Li /// lookup functions.
675*67e74705SXin Li llvm::Type *SlotTy;
676*67e74705SXin Li
677*67e74705SXin Li public:
678*67e74705SXin Li llvm::Constant *GetEHType(QualType T) override;
679*67e74705SXin Li
680*67e74705SXin Li protected:
LookupIMP(CodeGenFunction & CGF,llvm::Value * & Receiver,llvm::Value * cmd,llvm::MDNode * node,MessageSendInfo & MSI)681*67e74705SXin Li llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
682*67e74705SXin Li llvm::Value *cmd, llvm::MDNode *node,
683*67e74705SXin Li MessageSendInfo &MSI) override {
684*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
685*67e74705SXin Li llvm::Function *LookupFn = SlotLookupFn;
686*67e74705SXin Li
687*67e74705SXin Li // Store the receiver on the stack so that we can reload it later
688*67e74705SXin Li Address ReceiverPtr =
689*67e74705SXin Li CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign());
690*67e74705SXin Li Builder.CreateStore(Receiver, ReceiverPtr);
691*67e74705SXin Li
692*67e74705SXin Li llvm::Value *self;
693*67e74705SXin Li
694*67e74705SXin Li if (isa<ObjCMethodDecl>(CGF.CurCodeDecl)) {
695*67e74705SXin Li self = CGF.LoadObjCSelf();
696*67e74705SXin Li } else {
697*67e74705SXin Li self = llvm::ConstantPointerNull::get(IdTy);
698*67e74705SXin Li }
699*67e74705SXin Li
700*67e74705SXin Li // The lookup function is guaranteed not to capture the receiver pointer.
701*67e74705SXin Li LookupFn->setDoesNotCapture(1);
702*67e74705SXin Li
703*67e74705SXin Li llvm::Value *args[] = {
704*67e74705SXin Li EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy),
705*67e74705SXin Li EnforceType(Builder, cmd, SelectorTy),
706*67e74705SXin Li EnforceType(Builder, self, IdTy) };
707*67e74705SXin Li llvm::CallSite slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args);
708*67e74705SXin Li slot.setOnlyReadsMemory();
709*67e74705SXin Li slot->setMetadata(msgSendMDKind, node);
710*67e74705SXin Li
711*67e74705SXin Li // Load the imp from the slot
712*67e74705SXin Li llvm::Value *imp = Builder.CreateAlignedLoad(
713*67e74705SXin Li Builder.CreateStructGEP(nullptr, slot.getInstruction(), 4),
714*67e74705SXin Li CGF.getPointerAlign());
715*67e74705SXin Li
716*67e74705SXin Li // The lookup function may have changed the receiver, so make sure we use
717*67e74705SXin Li // the new one.
718*67e74705SXin Li Receiver = Builder.CreateLoad(ReceiverPtr, true);
719*67e74705SXin Li return imp;
720*67e74705SXin Li }
721*67e74705SXin Li
LookupIMPSuper(CodeGenFunction & CGF,Address ObjCSuper,llvm::Value * cmd,MessageSendInfo & MSI)722*67e74705SXin Li llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
723*67e74705SXin Li llvm::Value *cmd,
724*67e74705SXin Li MessageSendInfo &MSI) override {
725*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
726*67e74705SXin Li llvm::Value *lookupArgs[] = {ObjCSuper.getPointer(), cmd};
727*67e74705SXin Li
728*67e74705SXin Li llvm::CallInst *slot =
729*67e74705SXin Li CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs);
730*67e74705SXin Li slot->setOnlyReadsMemory();
731*67e74705SXin Li
732*67e74705SXin Li return Builder.CreateAlignedLoad(Builder.CreateStructGEP(nullptr, slot, 4),
733*67e74705SXin Li CGF.getPointerAlign());
734*67e74705SXin Li }
735*67e74705SXin Li
736*67e74705SXin Li public:
CGObjCGNUstep(CodeGenModule & Mod)737*67e74705SXin Li CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNU(Mod, 9, 3) {
738*67e74705SXin Li const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime;
739*67e74705SXin Li
740*67e74705SXin Li llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy,
741*67e74705SXin Li PtrTy, PtrTy, IntTy, IMPTy, nullptr);
742*67e74705SXin Li SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
743*67e74705SXin Li // Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
744*67e74705SXin Li SlotLookupFn.init(&CGM, "objc_msg_lookup_sender", SlotTy, PtrToIdTy,
745*67e74705SXin Li SelectorTy, IdTy, nullptr);
746*67e74705SXin Li // Slot_t objc_msg_lookup_super(struct objc_super*, SEL);
747*67e74705SXin Li SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
748*67e74705SXin Li PtrToObjCSuperTy, SelectorTy, nullptr);
749*67e74705SXin Li // If we're in ObjC++ mode, then we want to make
750*67e74705SXin Li if (CGM.getLangOpts().CPlusPlus) {
751*67e74705SXin Li llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
752*67e74705SXin Li // void *__cxa_begin_catch(void *e)
753*67e74705SXin Li EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy, nullptr);
754*67e74705SXin Li // void __cxa_end_catch(void)
755*67e74705SXin Li ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, nullptr);
756*67e74705SXin Li // void _Unwind_Resume_or_Rethrow(void*)
757*67e74705SXin Li ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy,
758*67e74705SXin Li PtrTy, nullptr);
759*67e74705SXin Li } else if (R.getVersion() >= VersionTuple(1, 7)) {
760*67e74705SXin Li llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
761*67e74705SXin Li // id objc_begin_catch(void *e)
762*67e74705SXin Li EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy, nullptr);
763*67e74705SXin Li // void objc_end_catch(void)
764*67e74705SXin Li ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy, nullptr);
765*67e74705SXin Li // void _Unwind_Resume_or_Rethrow(void*)
766*67e74705SXin Li ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy,
767*67e74705SXin Li PtrTy, nullptr);
768*67e74705SXin Li }
769*67e74705SXin Li llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
770*67e74705SXin Li SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy,
771*67e74705SXin Li SelectorTy, IdTy, PtrDiffTy, nullptr);
772*67e74705SXin Li SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy,
773*67e74705SXin Li IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
774*67e74705SXin Li SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy,
775*67e74705SXin Li IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
776*67e74705SXin Li SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy",
777*67e74705SXin Li VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
778*67e74705SXin Li // void objc_setCppObjectAtomic(void *dest, const void *src, void
779*67e74705SXin Li // *helper);
780*67e74705SXin Li CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy,
781*67e74705SXin Li PtrTy, PtrTy, nullptr);
782*67e74705SXin Li // void objc_getCppObjectAtomic(void *dest, const void *src, void
783*67e74705SXin Li // *helper);
784*67e74705SXin Li CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy,
785*67e74705SXin Li PtrTy, PtrTy, nullptr);
786*67e74705SXin Li }
787*67e74705SXin Li
GetCppAtomicObjectGetFunction()788*67e74705SXin Li llvm::Constant *GetCppAtomicObjectGetFunction() override {
789*67e74705SXin Li // The optimised functions were added in version 1.7 of the GNUstep
790*67e74705SXin Li // runtime.
791*67e74705SXin Li assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
792*67e74705SXin Li VersionTuple(1, 7));
793*67e74705SXin Li return CxxAtomicObjectGetFn;
794*67e74705SXin Li }
795*67e74705SXin Li
GetCppAtomicObjectSetFunction()796*67e74705SXin Li llvm::Constant *GetCppAtomicObjectSetFunction() override {
797*67e74705SXin Li // The optimised functions were added in version 1.7 of the GNUstep
798*67e74705SXin Li // runtime.
799*67e74705SXin Li assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
800*67e74705SXin Li VersionTuple(1, 7));
801*67e74705SXin Li return CxxAtomicObjectSetFn;
802*67e74705SXin Li }
803*67e74705SXin Li
GetOptimizedPropertySetFunction(bool atomic,bool copy)804*67e74705SXin Li llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
805*67e74705SXin Li bool copy) override {
806*67e74705SXin Li // The optimised property functions omit the GC check, and so are not
807*67e74705SXin Li // safe to use in GC mode. The standard functions are fast in GC mode,
808*67e74705SXin Li // so there is less advantage in using them.
809*67e74705SXin Li assert ((CGM.getLangOpts().getGC() == LangOptions::NonGC));
810*67e74705SXin Li // The optimised functions were added in version 1.7 of the GNUstep
811*67e74705SXin Li // runtime.
812*67e74705SXin Li assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
813*67e74705SXin Li VersionTuple(1, 7));
814*67e74705SXin Li
815*67e74705SXin Li if (atomic) {
816*67e74705SXin Li if (copy) return SetPropertyAtomicCopy;
817*67e74705SXin Li return SetPropertyAtomic;
818*67e74705SXin Li }
819*67e74705SXin Li
820*67e74705SXin Li return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
821*67e74705SXin Li }
822*67e74705SXin Li };
823*67e74705SXin Li
824*67e74705SXin Li /// Support for the ObjFW runtime.
825*67e74705SXin Li class CGObjCObjFW: public CGObjCGNU {
826*67e74705SXin Li protected:
827*67e74705SXin Li /// The GCC ABI message lookup function. Returns an IMP pointing to the
828*67e74705SXin Li /// method implementation for this message.
829*67e74705SXin Li LazyRuntimeFunction MsgLookupFn;
830*67e74705SXin Li /// stret lookup function. While this does not seem to make sense at the
831*67e74705SXin Li /// first look, this is required to call the correct forwarding function.
832*67e74705SXin Li LazyRuntimeFunction MsgLookupFnSRet;
833*67e74705SXin Li /// The GCC ABI superclass message lookup function. Takes a pointer to a
834*67e74705SXin Li /// structure describing the receiver and the class, and a selector as
835*67e74705SXin Li /// arguments. Returns the IMP for the corresponding method.
836*67e74705SXin Li LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
837*67e74705SXin Li
LookupIMP(CodeGenFunction & CGF,llvm::Value * & Receiver,llvm::Value * cmd,llvm::MDNode * node,MessageSendInfo & MSI)838*67e74705SXin Li llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
839*67e74705SXin Li llvm::Value *cmd, llvm::MDNode *node,
840*67e74705SXin Li MessageSendInfo &MSI) override {
841*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
842*67e74705SXin Li llvm::Value *args[] = {
843*67e74705SXin Li EnforceType(Builder, Receiver, IdTy),
844*67e74705SXin Li EnforceType(Builder, cmd, SelectorTy) };
845*67e74705SXin Li
846*67e74705SXin Li llvm::CallSite imp;
847*67e74705SXin Li if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
848*67e74705SXin Li imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFnSRet, args);
849*67e74705SXin Li else
850*67e74705SXin Li imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
851*67e74705SXin Li
852*67e74705SXin Li imp->setMetadata(msgSendMDKind, node);
853*67e74705SXin Li return imp.getInstruction();
854*67e74705SXin Li }
855*67e74705SXin Li
LookupIMPSuper(CodeGenFunction & CGF,Address ObjCSuper,llvm::Value * cmd,MessageSendInfo & MSI)856*67e74705SXin Li llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
857*67e74705SXin Li llvm::Value *cmd, MessageSendInfo &MSI) override {
858*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
859*67e74705SXin Li llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper.getPointer(),
860*67e74705SXin Li PtrToObjCSuperTy), cmd};
861*67e74705SXin Li
862*67e74705SXin Li if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
863*67e74705SXin Li return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFnSRet, lookupArgs);
864*67e74705SXin Li else
865*67e74705SXin Li return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs);
866*67e74705SXin Li }
867*67e74705SXin Li
GetClassNamed(CodeGenFunction & CGF,const std::string & Name,bool isWeak)868*67e74705SXin Li llvm::Value *GetClassNamed(CodeGenFunction &CGF,
869*67e74705SXin Li const std::string &Name, bool isWeak) override {
870*67e74705SXin Li if (isWeak)
871*67e74705SXin Li return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
872*67e74705SXin Li
873*67e74705SXin Li EmitClassRef(Name);
874*67e74705SXin Li
875*67e74705SXin Li std::string SymbolName = "_OBJC_CLASS_" + Name;
876*67e74705SXin Li
877*67e74705SXin Li llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
878*67e74705SXin Li
879*67e74705SXin Li if (!ClassSymbol)
880*67e74705SXin Li ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
881*67e74705SXin Li llvm::GlobalValue::ExternalLinkage,
882*67e74705SXin Li nullptr, SymbolName);
883*67e74705SXin Li
884*67e74705SXin Li return ClassSymbol;
885*67e74705SXin Li }
886*67e74705SXin Li
887*67e74705SXin Li public:
CGObjCObjFW(CodeGenModule & Mod)888*67e74705SXin Li CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {
889*67e74705SXin Li // IMP objc_msg_lookup(id, SEL);
890*67e74705SXin Li MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, nullptr);
891*67e74705SXin Li MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy,
892*67e74705SXin Li SelectorTy, nullptr);
893*67e74705SXin Li // IMP objc_msg_lookup_super(struct objc_super*, SEL);
894*67e74705SXin Li MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
895*67e74705SXin Li PtrToObjCSuperTy, SelectorTy, nullptr);
896*67e74705SXin Li MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy,
897*67e74705SXin Li PtrToObjCSuperTy, SelectorTy, nullptr);
898*67e74705SXin Li }
899*67e74705SXin Li };
900*67e74705SXin Li } // end anonymous namespace
901*67e74705SXin Li
902*67e74705SXin Li /// Emits a reference to a dummy variable which is emitted with each class.
903*67e74705SXin Li /// This ensures that a linker error will be generated when trying to link
904*67e74705SXin Li /// together modules where a referenced class is not defined.
EmitClassRef(const std::string & className)905*67e74705SXin Li void CGObjCGNU::EmitClassRef(const std::string &className) {
906*67e74705SXin Li std::string symbolRef = "__objc_class_ref_" + className;
907*67e74705SXin Li // Don't emit two copies of the same symbol
908*67e74705SXin Li if (TheModule.getGlobalVariable(symbolRef))
909*67e74705SXin Li return;
910*67e74705SXin Li std::string symbolName = "__objc_class_name_" + className;
911*67e74705SXin Li llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
912*67e74705SXin Li if (!ClassSymbol) {
913*67e74705SXin Li ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
914*67e74705SXin Li llvm::GlobalValue::ExternalLinkage,
915*67e74705SXin Li nullptr, symbolName);
916*67e74705SXin Li }
917*67e74705SXin Li new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
918*67e74705SXin Li llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
919*67e74705SXin Li }
920*67e74705SXin Li
SymbolNameForMethod(StringRef ClassName,StringRef CategoryName,const Selector MethodName,bool isClassMethod)921*67e74705SXin Li static std::string SymbolNameForMethod( StringRef ClassName,
922*67e74705SXin Li StringRef CategoryName, const Selector MethodName,
923*67e74705SXin Li bool isClassMethod) {
924*67e74705SXin Li std::string MethodNameColonStripped = MethodName.getAsString();
925*67e74705SXin Li std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
926*67e74705SXin Li ':', '_');
927*67e74705SXin Li return (Twine(isClassMethod ? "_c_" : "_i_") + ClassName + "_" +
928*67e74705SXin Li CategoryName + "_" + MethodNameColonStripped).str();
929*67e74705SXin Li }
930*67e74705SXin Li
CGObjCGNU(CodeGenModule & cgm,unsigned runtimeABIVersion,unsigned protocolClassVersion)931*67e74705SXin Li CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
932*67e74705SXin Li unsigned protocolClassVersion)
933*67e74705SXin Li : CGObjCRuntime(cgm), TheModule(CGM.getModule()),
934*67e74705SXin Li VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
935*67e74705SXin Li MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
936*67e74705SXin Li ProtocolVersion(protocolClassVersion) {
937*67e74705SXin Li
938*67e74705SXin Li msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
939*67e74705SXin Li
940*67e74705SXin Li CodeGenTypes &Types = CGM.getTypes();
941*67e74705SXin Li IntTy = cast<llvm::IntegerType>(
942*67e74705SXin Li Types.ConvertType(CGM.getContext().IntTy));
943*67e74705SXin Li LongTy = cast<llvm::IntegerType>(
944*67e74705SXin Li Types.ConvertType(CGM.getContext().LongTy));
945*67e74705SXin Li SizeTy = cast<llvm::IntegerType>(
946*67e74705SXin Li Types.ConvertType(CGM.getContext().getSizeType()));
947*67e74705SXin Li PtrDiffTy = cast<llvm::IntegerType>(
948*67e74705SXin Li Types.ConvertType(CGM.getContext().getPointerDiffType()));
949*67e74705SXin Li BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
950*67e74705SXin Li
951*67e74705SXin Li Int8Ty = llvm::Type::getInt8Ty(VMContext);
952*67e74705SXin Li // C string type. Used in lots of places.
953*67e74705SXin Li PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
954*67e74705SXin Li
955*67e74705SXin Li Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
956*67e74705SXin Li Zeros[1] = Zeros[0];
957*67e74705SXin Li NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
958*67e74705SXin Li // Get the selector Type.
959*67e74705SXin Li QualType selTy = CGM.getContext().getObjCSelType();
960*67e74705SXin Li if (QualType() == selTy) {
961*67e74705SXin Li SelectorTy = PtrToInt8Ty;
962*67e74705SXin Li } else {
963*67e74705SXin Li SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
964*67e74705SXin Li }
965*67e74705SXin Li
966*67e74705SXin Li PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
967*67e74705SXin Li PtrTy = PtrToInt8Ty;
968*67e74705SXin Li
969*67e74705SXin Li Int32Ty = llvm::Type::getInt32Ty(VMContext);
970*67e74705SXin Li Int64Ty = llvm::Type::getInt64Ty(VMContext);
971*67e74705SXin Li
972*67e74705SXin Li IntPtrTy =
973*67e74705SXin Li CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
974*67e74705SXin Li
975*67e74705SXin Li // Object type
976*67e74705SXin Li QualType UnqualIdTy = CGM.getContext().getObjCIdType();
977*67e74705SXin Li ASTIdTy = CanQualType();
978*67e74705SXin Li if (UnqualIdTy != QualType()) {
979*67e74705SXin Li ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy);
980*67e74705SXin Li IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
981*67e74705SXin Li } else {
982*67e74705SXin Li IdTy = PtrToInt8Ty;
983*67e74705SXin Li }
984*67e74705SXin Li PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
985*67e74705SXin Li
986*67e74705SXin Li ObjCSuperTy = llvm::StructType::get(IdTy, IdTy, nullptr);
987*67e74705SXin Li PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
988*67e74705SXin Li
989*67e74705SXin Li llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
990*67e74705SXin Li
991*67e74705SXin Li // void objc_exception_throw(id);
992*67e74705SXin Li ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, nullptr);
993*67e74705SXin Li ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, nullptr);
994*67e74705SXin Li // int objc_sync_enter(id);
995*67e74705SXin Li SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy, nullptr);
996*67e74705SXin Li // int objc_sync_exit(id);
997*67e74705SXin Li SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy, nullptr);
998*67e74705SXin Li
999*67e74705SXin Li // void objc_enumerationMutation (id)
1000*67e74705SXin Li EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy,
1001*67e74705SXin Li IdTy, nullptr);
1002*67e74705SXin Li
1003*67e74705SXin Li // id objc_getProperty(id, SEL, ptrdiff_t, BOOL)
1004*67e74705SXin Li GetPropertyFn.init(&CGM, "objc_getProperty", IdTy, IdTy, SelectorTy,
1005*67e74705SXin Li PtrDiffTy, BoolTy, nullptr);
1006*67e74705SXin Li // void objc_setProperty(id, SEL, ptrdiff_t, id, BOOL, BOOL)
1007*67e74705SXin Li SetPropertyFn.init(&CGM, "objc_setProperty", VoidTy, IdTy, SelectorTy,
1008*67e74705SXin Li PtrDiffTy, IdTy, BoolTy, BoolTy, nullptr);
1009*67e74705SXin Li // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL)
1010*67e74705SXin Li GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
1011*67e74705SXin Li PtrDiffTy, BoolTy, BoolTy, nullptr);
1012*67e74705SXin Li // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL)
1013*67e74705SXin Li SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
1014*67e74705SXin Li PtrDiffTy, BoolTy, BoolTy, nullptr);
1015*67e74705SXin Li
1016*67e74705SXin Li // IMP type
1017*67e74705SXin Li llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
1018*67e74705SXin Li IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
1019*67e74705SXin Li true));
1020*67e74705SXin Li
1021*67e74705SXin Li const LangOptions &Opts = CGM.getLangOpts();
1022*67e74705SXin Li if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
1023*67e74705SXin Li RuntimeVersion = 10;
1024*67e74705SXin Li
1025*67e74705SXin Li // Don't bother initialising the GC stuff unless we're compiling in GC mode
1026*67e74705SXin Li if (Opts.getGC() != LangOptions::NonGC) {
1027*67e74705SXin Li // This is a bit of an hack. We should sort this out by having a proper
1028*67e74705SXin Li // CGObjCGNUstep subclass for GC, but we may want to really support the old
1029*67e74705SXin Li // ABI and GC added in ObjectiveC2.framework, so we fudge it a bit for now
1030*67e74705SXin Li // Get selectors needed in GC mode
1031*67e74705SXin Li RetainSel = GetNullarySelector("retain", CGM.getContext());
1032*67e74705SXin Li ReleaseSel = GetNullarySelector("release", CGM.getContext());
1033*67e74705SXin Li AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext());
1034*67e74705SXin Li
1035*67e74705SXin Li // Get functions needed in GC mode
1036*67e74705SXin Li
1037*67e74705SXin Li // id objc_assign_ivar(id, id, ptrdiff_t);
1038*67e74705SXin Li IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy,
1039*67e74705SXin Li nullptr);
1040*67e74705SXin Li // id objc_assign_strongCast (id, id*)
1041*67e74705SXin Li StrongCastAssignFn.init(&CGM, "objc_assign_strongCast", IdTy, IdTy,
1042*67e74705SXin Li PtrToIdTy, nullptr);
1043*67e74705SXin Li // id objc_assign_global(id, id*);
1044*67e74705SXin Li GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy,
1045*67e74705SXin Li nullptr);
1046*67e74705SXin Li // id objc_assign_weak(id, id*);
1047*67e74705SXin Li WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy, nullptr);
1048*67e74705SXin Li // id objc_read_weak(id*);
1049*67e74705SXin Li WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy, nullptr);
1050*67e74705SXin Li // void *objc_memmove_collectable(void*, void *, size_t);
1051*67e74705SXin Li MemMoveFn.init(&CGM, "objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
1052*67e74705SXin Li SizeTy, nullptr);
1053*67e74705SXin Li }
1054*67e74705SXin Li }
1055*67e74705SXin Li
GetClassNamed(CodeGenFunction & CGF,const std::string & Name,bool isWeak)1056*67e74705SXin Li llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF,
1057*67e74705SXin Li const std::string &Name,
1058*67e74705SXin Li bool isWeak) {
1059*67e74705SXin Li llvm::Constant *ClassName = MakeConstantString(Name);
1060*67e74705SXin Li // With the incompatible ABI, this will need to be replaced with a direct
1061*67e74705SXin Li // reference to the class symbol. For the compatible nonfragile ABI we are
1062*67e74705SXin Li // still performing this lookup at run time but emitting the symbol for the
1063*67e74705SXin Li // class externally so that we can make the switch later.
1064*67e74705SXin Li //
1065*67e74705SXin Li // Libobjc2 contains an LLVM pass that replaces calls to objc_lookup_class
1066*67e74705SXin Li // with memoized versions or with static references if it's safe to do so.
1067*67e74705SXin Li if (!isWeak)
1068*67e74705SXin Li EmitClassRef(Name);
1069*67e74705SXin Li
1070*67e74705SXin Li llvm::Constant *ClassLookupFn =
1071*67e74705SXin Li CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty, true),
1072*67e74705SXin Li "objc_lookup_class");
1073*67e74705SXin Li return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName);
1074*67e74705SXin Li }
1075*67e74705SXin Li
1076*67e74705SXin Li // This has to perform the lookup every time, since posing and related
1077*67e74705SXin Li // techniques can modify the name -> class mapping.
GetClass(CodeGenFunction & CGF,const ObjCInterfaceDecl * OID)1078*67e74705SXin Li llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF,
1079*67e74705SXin Li const ObjCInterfaceDecl *OID) {
1080*67e74705SXin Li return GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported());
1081*67e74705SXin Li }
1082*67e74705SXin Li
EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)1083*67e74705SXin Li llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
1084*67e74705SXin Li return GetClassNamed(CGF, "NSAutoreleasePool", false);
1085*67e74705SXin Li }
1086*67e74705SXin Li
GetSelector(CodeGenFunction & CGF,Selector Sel,const std::string & TypeEncoding)1087*67e74705SXin Li llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel,
1088*67e74705SXin Li const std::string &TypeEncoding) {
1089*67e74705SXin Li SmallVectorImpl<TypedSelector> &Types = SelectorTable[Sel];
1090*67e74705SXin Li llvm::GlobalAlias *SelValue = nullptr;
1091*67e74705SXin Li
1092*67e74705SXin Li for (SmallVectorImpl<TypedSelector>::iterator i = Types.begin(),
1093*67e74705SXin Li e = Types.end() ; i!=e ; i++) {
1094*67e74705SXin Li if (i->first == TypeEncoding) {
1095*67e74705SXin Li SelValue = i->second;
1096*67e74705SXin Li break;
1097*67e74705SXin Li }
1098*67e74705SXin Li }
1099*67e74705SXin Li if (!SelValue) {
1100*67e74705SXin Li SelValue = llvm::GlobalAlias::create(
1101*67e74705SXin Li SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
1102*67e74705SXin Li ".objc_selector_" + Sel.getAsString(), &TheModule);
1103*67e74705SXin Li Types.emplace_back(TypeEncoding, SelValue);
1104*67e74705SXin Li }
1105*67e74705SXin Li
1106*67e74705SXin Li return SelValue;
1107*67e74705SXin Li }
1108*67e74705SXin Li
GetAddrOfSelector(CodeGenFunction & CGF,Selector Sel)1109*67e74705SXin Li Address CGObjCGNU::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
1110*67e74705SXin Li llvm::Value *SelValue = GetSelector(CGF, Sel);
1111*67e74705SXin Li
1112*67e74705SXin Li // Store it to a temporary. Does this satisfy the semantics of
1113*67e74705SXin Li // GetAddrOfSelector? Hopefully.
1114*67e74705SXin Li Address tmp = CGF.CreateTempAlloca(SelValue->getType(),
1115*67e74705SXin Li CGF.getPointerAlign());
1116*67e74705SXin Li CGF.Builder.CreateStore(SelValue, tmp);
1117*67e74705SXin Li return tmp;
1118*67e74705SXin Li }
1119*67e74705SXin Li
GetSelector(CodeGenFunction & CGF,Selector Sel)1120*67e74705SXin Li llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel) {
1121*67e74705SXin Li return GetSelector(CGF, Sel, std::string());
1122*67e74705SXin Li }
1123*67e74705SXin Li
GetSelector(CodeGenFunction & CGF,const ObjCMethodDecl * Method)1124*67e74705SXin Li llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF,
1125*67e74705SXin Li const ObjCMethodDecl *Method) {
1126*67e74705SXin Li std::string SelTypes;
1127*67e74705SXin Li CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
1128*67e74705SXin Li return GetSelector(CGF, Method->getSelector(), SelTypes);
1129*67e74705SXin Li }
1130*67e74705SXin Li
GetEHType(QualType T)1131*67e74705SXin Li llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
1132*67e74705SXin Li if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
1133*67e74705SXin Li // With the old ABI, there was only one kind of catchall, which broke
1134*67e74705SXin Li // foreign exceptions. With the new ABI, we use __objc_id_typeinfo as
1135*67e74705SXin Li // a pointer indicating object catchalls, and NULL to indicate real
1136*67e74705SXin Li // catchalls
1137*67e74705SXin Li if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
1138*67e74705SXin Li return MakeConstantString("@id");
1139*67e74705SXin Li } else {
1140*67e74705SXin Li return nullptr;
1141*67e74705SXin Li }
1142*67e74705SXin Li }
1143*67e74705SXin Li
1144*67e74705SXin Li // All other types should be Objective-C interface pointer types.
1145*67e74705SXin Li const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>();
1146*67e74705SXin Li assert(OPT && "Invalid @catch type.");
1147*67e74705SXin Li const ObjCInterfaceDecl *IDecl = OPT->getObjectType()->getInterface();
1148*67e74705SXin Li assert(IDecl && "Invalid @catch type.");
1149*67e74705SXin Li return MakeConstantString(IDecl->getIdentifier()->getName());
1150*67e74705SXin Li }
1151*67e74705SXin Li
GetEHType(QualType T)1152*67e74705SXin Li llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
1153*67e74705SXin Li if (!CGM.getLangOpts().CPlusPlus)
1154*67e74705SXin Li return CGObjCGNU::GetEHType(T);
1155*67e74705SXin Li
1156*67e74705SXin Li // For Objective-C++, we want to provide the ability to catch both C++ and
1157*67e74705SXin Li // Objective-C objects in the same function.
1158*67e74705SXin Li
1159*67e74705SXin Li // There's a particular fixed type info for 'id'.
1160*67e74705SXin Li if (T->isObjCIdType() ||
1161*67e74705SXin Li T->isObjCQualifiedIdType()) {
1162*67e74705SXin Li llvm::Constant *IDEHType =
1163*67e74705SXin Li CGM.getModule().getGlobalVariable("__objc_id_type_info");
1164*67e74705SXin Li if (!IDEHType)
1165*67e74705SXin Li IDEHType =
1166*67e74705SXin Li new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
1167*67e74705SXin Li false,
1168*67e74705SXin Li llvm::GlobalValue::ExternalLinkage,
1169*67e74705SXin Li nullptr, "__objc_id_type_info");
1170*67e74705SXin Li return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
1171*67e74705SXin Li }
1172*67e74705SXin Li
1173*67e74705SXin Li const ObjCObjectPointerType *PT =
1174*67e74705SXin Li T->getAs<ObjCObjectPointerType>();
1175*67e74705SXin Li assert(PT && "Invalid @catch type.");
1176*67e74705SXin Li const ObjCInterfaceType *IT = PT->getInterfaceType();
1177*67e74705SXin Li assert(IT && "Invalid @catch type.");
1178*67e74705SXin Li std::string className = IT->getDecl()->getIdentifier()->getName();
1179*67e74705SXin Li
1180*67e74705SXin Li std::string typeinfoName = "__objc_eh_typeinfo_" + className;
1181*67e74705SXin Li
1182*67e74705SXin Li // Return the existing typeinfo if it exists
1183*67e74705SXin Li llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
1184*67e74705SXin Li if (typeinfo)
1185*67e74705SXin Li return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
1186*67e74705SXin Li
1187*67e74705SXin Li // Otherwise create it.
1188*67e74705SXin Li
1189*67e74705SXin Li // vtable for gnustep::libobjc::__objc_class_type_info
1190*67e74705SXin Li // It's quite ugly hard-coding this. Ideally we'd generate it using the host
1191*67e74705SXin Li // platform's name mangling.
1192*67e74705SXin Li const char *vtableName = "_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
1193*67e74705SXin Li auto *Vtable = TheModule.getGlobalVariable(vtableName);
1194*67e74705SXin Li if (!Vtable) {
1195*67e74705SXin Li Vtable = new llvm::GlobalVariable(TheModule, PtrToInt8Ty, true,
1196*67e74705SXin Li llvm::GlobalValue::ExternalLinkage,
1197*67e74705SXin Li nullptr, vtableName);
1198*67e74705SXin Li }
1199*67e74705SXin Li llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
1200*67e74705SXin Li auto *BVtable = llvm::ConstantExpr::getBitCast(
1201*67e74705SXin Li llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
1202*67e74705SXin Li PtrToInt8Ty);
1203*67e74705SXin Li
1204*67e74705SXin Li llvm::Constant *typeName =
1205*67e74705SXin Li ExportUniqueString(className, "__objc_eh_typename_");
1206*67e74705SXin Li
1207*67e74705SXin Li std::vector<llvm::Constant*> fields;
1208*67e74705SXin Li fields.push_back(BVtable);
1209*67e74705SXin Li fields.push_back(typeName);
1210*67e74705SXin Li llvm::Constant *TI =
1211*67e74705SXin Li MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, nullptr),
1212*67e74705SXin Li fields, CGM.getPointerAlign(),
1213*67e74705SXin Li "__objc_eh_typeinfo_" + className,
1214*67e74705SXin Li llvm::GlobalValue::LinkOnceODRLinkage);
1215*67e74705SXin Li return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
1216*67e74705SXin Li }
1217*67e74705SXin Li
1218*67e74705SXin Li /// Generate an NSConstantString object.
GenerateConstantString(const StringLiteral * SL)1219*67e74705SXin Li ConstantAddress CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
1220*67e74705SXin Li
1221*67e74705SXin Li std::string Str = SL->getString().str();
1222*67e74705SXin Li CharUnits Align = CGM.getPointerAlign();
1223*67e74705SXin Li
1224*67e74705SXin Li // Look for an existing one
1225*67e74705SXin Li llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
1226*67e74705SXin Li if (old != ObjCStrings.end())
1227*67e74705SXin Li return ConstantAddress(old->getValue(), Align);
1228*67e74705SXin Li
1229*67e74705SXin Li StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1230*67e74705SXin Li
1231*67e74705SXin Li if (StringClass.empty()) StringClass = "NXConstantString";
1232*67e74705SXin Li
1233*67e74705SXin Li std::string Sym = "_OBJC_CLASS_";
1234*67e74705SXin Li Sym += StringClass;
1235*67e74705SXin Li
1236*67e74705SXin Li llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
1237*67e74705SXin Li
1238*67e74705SXin Li if (!isa)
1239*67e74705SXin Li isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false,
1240*67e74705SXin Li llvm::GlobalValue::ExternalWeakLinkage, nullptr, Sym);
1241*67e74705SXin Li else if (isa->getType() != PtrToIdTy)
1242*67e74705SXin Li isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1243*67e74705SXin Li
1244*67e74705SXin Li std::vector<llvm::Constant*> Ivars;
1245*67e74705SXin Li Ivars.push_back(isa);
1246*67e74705SXin Li Ivars.push_back(MakeConstantString(Str));
1247*67e74705SXin Li Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
1248*67e74705SXin Li llvm::Constant *ObjCStr = MakeGlobal(
1249*67e74705SXin Li llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy, nullptr),
1250*67e74705SXin Li Ivars, Align, ".objc_str");
1251*67e74705SXin Li ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
1252*67e74705SXin Li ObjCStrings[Str] = ObjCStr;
1253*67e74705SXin Li ConstantStrings.push_back(ObjCStr);
1254*67e74705SXin Li return ConstantAddress(ObjCStr, Align);
1255*67e74705SXin Li }
1256*67e74705SXin Li
1257*67e74705SXin Li ///Generates a message send where the super is the receiver. This is a message
1258*67e74705SXin Li ///send to self with special delivery semantics indicating which class's method
1259*67e74705SXin Li ///should be called.
1260*67e74705SXin Li RValue
GenerateMessageSendSuper(CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,const ObjCInterfaceDecl * Class,bool isCategoryImpl,llvm::Value * Receiver,bool IsClassMessage,const CallArgList & CallArgs,const ObjCMethodDecl * Method)1261*67e74705SXin Li CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
1262*67e74705SXin Li ReturnValueSlot Return,
1263*67e74705SXin Li QualType ResultType,
1264*67e74705SXin Li Selector Sel,
1265*67e74705SXin Li const ObjCInterfaceDecl *Class,
1266*67e74705SXin Li bool isCategoryImpl,
1267*67e74705SXin Li llvm::Value *Receiver,
1268*67e74705SXin Li bool IsClassMessage,
1269*67e74705SXin Li const CallArgList &CallArgs,
1270*67e74705SXin Li const ObjCMethodDecl *Method) {
1271*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
1272*67e74705SXin Li if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1273*67e74705SXin Li if (Sel == RetainSel || Sel == AutoreleaseSel) {
1274*67e74705SXin Li return RValue::get(EnforceType(Builder, Receiver,
1275*67e74705SXin Li CGM.getTypes().ConvertType(ResultType)));
1276*67e74705SXin Li }
1277*67e74705SXin Li if (Sel == ReleaseSel) {
1278*67e74705SXin Li return RValue::get(nullptr);
1279*67e74705SXin Li }
1280*67e74705SXin Li }
1281*67e74705SXin Li
1282*67e74705SXin Li llvm::Value *cmd = GetSelector(CGF, Sel);
1283*67e74705SXin Li CallArgList ActualArgs;
1284*67e74705SXin Li
1285*67e74705SXin Li ActualArgs.add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
1286*67e74705SXin Li ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType());
1287*67e74705SXin Li ActualArgs.addFrom(CallArgs);
1288*67e74705SXin Li
1289*67e74705SXin Li MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1290*67e74705SXin Li
1291*67e74705SXin Li llvm::Value *ReceiverClass = nullptr;
1292*67e74705SXin Li if (isCategoryImpl) {
1293*67e74705SXin Li llvm::Constant *classLookupFunction = nullptr;
1294*67e74705SXin Li if (IsClassMessage) {
1295*67e74705SXin Li classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1296*67e74705SXin Li IdTy, PtrTy, true), "objc_get_meta_class");
1297*67e74705SXin Li } else {
1298*67e74705SXin Li classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1299*67e74705SXin Li IdTy, PtrTy, true), "objc_get_class");
1300*67e74705SXin Li }
1301*67e74705SXin Li ReceiverClass = Builder.CreateCall(classLookupFunction,
1302*67e74705SXin Li MakeConstantString(Class->getNameAsString()));
1303*67e74705SXin Li } else {
1304*67e74705SXin Li // Set up global aliases for the metaclass or class pointer if they do not
1305*67e74705SXin Li // already exist. These will are forward-references which will be set to
1306*67e74705SXin Li // pointers to the class and metaclass structure created for the runtime
1307*67e74705SXin Li // load function. To send a message to super, we look up the value of the
1308*67e74705SXin Li // super_class pointer from either the class or metaclass structure.
1309*67e74705SXin Li if (IsClassMessage) {
1310*67e74705SXin Li if (!MetaClassPtrAlias) {
1311*67e74705SXin Li MetaClassPtrAlias = llvm::GlobalAlias::create(
1312*67e74705SXin Li IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage,
1313*67e74705SXin Li ".objc_metaclass_ref" + Class->getNameAsString(), &TheModule);
1314*67e74705SXin Li }
1315*67e74705SXin Li ReceiverClass = MetaClassPtrAlias;
1316*67e74705SXin Li } else {
1317*67e74705SXin Li if (!ClassPtrAlias) {
1318*67e74705SXin Li ClassPtrAlias = llvm::GlobalAlias::create(
1319*67e74705SXin Li IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage,
1320*67e74705SXin Li ".objc_class_ref" + Class->getNameAsString(), &TheModule);
1321*67e74705SXin Li }
1322*67e74705SXin Li ReceiverClass = ClassPtrAlias;
1323*67e74705SXin Li }
1324*67e74705SXin Li }
1325*67e74705SXin Li // Cast the pointer to a simplified version of the class structure
1326*67e74705SXin Li llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy, nullptr);
1327*67e74705SXin Li ReceiverClass = Builder.CreateBitCast(ReceiverClass,
1328*67e74705SXin Li llvm::PointerType::getUnqual(CastTy));
1329*67e74705SXin Li // Get the superclass pointer
1330*67e74705SXin Li ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
1331*67e74705SXin Li // Load the superclass pointer
1332*67e74705SXin Li ReceiverClass =
1333*67e74705SXin Li Builder.CreateAlignedLoad(ReceiverClass, CGF.getPointerAlign());
1334*67e74705SXin Li // Construct the structure used to look up the IMP
1335*67e74705SXin Li llvm::StructType *ObjCSuperTy = llvm::StructType::get(
1336*67e74705SXin Li Receiver->getType(), IdTy, nullptr);
1337*67e74705SXin Li
1338*67e74705SXin Li // FIXME: Is this really supposed to be a dynamic alloca?
1339*67e74705SXin Li Address ObjCSuper = Address(Builder.CreateAlloca(ObjCSuperTy),
1340*67e74705SXin Li CGF.getPointerAlign());
1341*67e74705SXin Li
1342*67e74705SXin Li Builder.CreateStore(Receiver,
1343*67e74705SXin Li Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
1344*67e74705SXin Li Builder.CreateStore(ReceiverClass,
1345*67e74705SXin Li Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
1346*67e74705SXin Li
1347*67e74705SXin Li ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
1348*67e74705SXin Li
1349*67e74705SXin Li // Get the IMP
1350*67e74705SXin Li llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
1351*67e74705SXin Li imp = EnforceType(Builder, imp, MSI.MessengerType);
1352*67e74705SXin Li
1353*67e74705SXin Li llvm::Metadata *impMD[] = {
1354*67e74705SXin Li llvm::MDString::get(VMContext, Sel.getAsString()),
1355*67e74705SXin Li llvm::MDString::get(VMContext, Class->getSuperClass()->getNameAsString()),
1356*67e74705SXin Li llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1357*67e74705SXin Li llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
1358*67e74705SXin Li llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1359*67e74705SXin Li
1360*67e74705SXin Li llvm::Instruction *call;
1361*67e74705SXin Li RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
1362*67e74705SXin Li CGCalleeInfo(), &call);
1363*67e74705SXin Li call->setMetadata(msgSendMDKind, node);
1364*67e74705SXin Li return msgRet;
1365*67e74705SXin Li }
1366*67e74705SXin Li
1367*67e74705SXin Li /// Generate code for a message send expression.
1368*67e74705SXin Li RValue
GenerateMessageSend(CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,llvm::Value * Receiver,const CallArgList & CallArgs,const ObjCInterfaceDecl * Class,const ObjCMethodDecl * Method)1369*67e74705SXin Li CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
1370*67e74705SXin Li ReturnValueSlot Return,
1371*67e74705SXin Li QualType ResultType,
1372*67e74705SXin Li Selector Sel,
1373*67e74705SXin Li llvm::Value *Receiver,
1374*67e74705SXin Li const CallArgList &CallArgs,
1375*67e74705SXin Li const ObjCInterfaceDecl *Class,
1376*67e74705SXin Li const ObjCMethodDecl *Method) {
1377*67e74705SXin Li CGBuilderTy &Builder = CGF.Builder;
1378*67e74705SXin Li
1379*67e74705SXin Li // Strip out message sends to retain / release in GC mode
1380*67e74705SXin Li if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1381*67e74705SXin Li if (Sel == RetainSel || Sel == AutoreleaseSel) {
1382*67e74705SXin Li return RValue::get(EnforceType(Builder, Receiver,
1383*67e74705SXin Li CGM.getTypes().ConvertType(ResultType)));
1384*67e74705SXin Li }
1385*67e74705SXin Li if (Sel == ReleaseSel) {
1386*67e74705SXin Li return RValue::get(nullptr);
1387*67e74705SXin Li }
1388*67e74705SXin Li }
1389*67e74705SXin Li
1390*67e74705SXin Li // If the return type is something that goes in an integer register, the
1391*67e74705SXin Li // runtime will handle 0 returns. For other cases, we fill in the 0 value
1392*67e74705SXin Li // ourselves.
1393*67e74705SXin Li //
1394*67e74705SXin Li // The language spec says the result of this kind of message send is
1395*67e74705SXin Li // undefined, but lots of people seem to have forgotten to read that
1396*67e74705SXin Li // paragraph and insist on sending messages to nil that have structure
1397*67e74705SXin Li // returns. With GCC, this generates a random return value (whatever happens
1398*67e74705SXin Li // to be on the stack / in those registers at the time) on most platforms,
1399*67e74705SXin Li // and generates an illegal instruction trap on SPARC. With LLVM it corrupts
1400*67e74705SXin Li // the stack.
1401*67e74705SXin Li bool isPointerSizedReturn = (ResultType->isAnyPointerType() ||
1402*67e74705SXin Li ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType());
1403*67e74705SXin Li
1404*67e74705SXin Li llvm::BasicBlock *startBB = nullptr;
1405*67e74705SXin Li llvm::BasicBlock *messageBB = nullptr;
1406*67e74705SXin Li llvm::BasicBlock *continueBB = nullptr;
1407*67e74705SXin Li
1408*67e74705SXin Li if (!isPointerSizedReturn) {
1409*67e74705SXin Li startBB = Builder.GetInsertBlock();
1410*67e74705SXin Li messageBB = CGF.createBasicBlock("msgSend");
1411*67e74705SXin Li continueBB = CGF.createBasicBlock("continue");
1412*67e74705SXin Li
1413*67e74705SXin Li llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
1414*67e74705SXin Li llvm::Constant::getNullValue(Receiver->getType()));
1415*67e74705SXin Li Builder.CreateCondBr(isNil, continueBB, messageBB);
1416*67e74705SXin Li CGF.EmitBlock(messageBB);
1417*67e74705SXin Li }
1418*67e74705SXin Li
1419*67e74705SXin Li IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
1420*67e74705SXin Li llvm::Value *cmd;
1421*67e74705SXin Li if (Method)
1422*67e74705SXin Li cmd = GetSelector(CGF, Method);
1423*67e74705SXin Li else
1424*67e74705SXin Li cmd = GetSelector(CGF, Sel);
1425*67e74705SXin Li cmd = EnforceType(Builder, cmd, SelectorTy);
1426*67e74705SXin Li Receiver = EnforceType(Builder, Receiver, IdTy);
1427*67e74705SXin Li
1428*67e74705SXin Li llvm::Metadata *impMD[] = {
1429*67e74705SXin Li llvm::MDString::get(VMContext, Sel.getAsString()),
1430*67e74705SXin Li llvm::MDString::get(VMContext, Class ? Class->getNameAsString() : ""),
1431*67e74705SXin Li llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1432*67e74705SXin Li llvm::Type::getInt1Ty(VMContext), Class != nullptr))};
1433*67e74705SXin Li llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1434*67e74705SXin Li
1435*67e74705SXin Li CallArgList ActualArgs;
1436*67e74705SXin Li ActualArgs.add(RValue::get(Receiver), ASTIdTy);
1437*67e74705SXin Li ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType());
1438*67e74705SXin Li ActualArgs.addFrom(CallArgs);
1439*67e74705SXin Li
1440*67e74705SXin Li MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1441*67e74705SXin Li
1442*67e74705SXin Li // Get the IMP to call
1443*67e74705SXin Li llvm::Value *imp;
1444*67e74705SXin Li
1445*67e74705SXin Li // If we have non-legacy dispatch specified, we try using the objc_msgSend()
1446*67e74705SXin Li // functions. These are not supported on all platforms (or all runtimes on a
1447*67e74705SXin Li // given platform), so we
1448*67e74705SXin Li switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
1449*67e74705SXin Li case CodeGenOptions::Legacy:
1450*67e74705SXin Li imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
1451*67e74705SXin Li break;
1452*67e74705SXin Li case CodeGenOptions::Mixed:
1453*67e74705SXin Li case CodeGenOptions::NonLegacy:
1454*67e74705SXin Li if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1455*67e74705SXin Li imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
1456*67e74705SXin Li "objc_msgSend_fpret");
1457*67e74705SXin Li } else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1458*67e74705SXin Li // The actual types here don't matter - we're going to bitcast the
1459*67e74705SXin Li // function anyway
1460*67e74705SXin Li imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
1461*67e74705SXin Li "objc_msgSend_stret");
1462*67e74705SXin Li } else {
1463*67e74705SXin Li imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
1464*67e74705SXin Li "objc_msgSend");
1465*67e74705SXin Li }
1466*67e74705SXin Li }
1467*67e74705SXin Li
1468*67e74705SXin Li // Reset the receiver in case the lookup modified it
1469*67e74705SXin Li ActualArgs[0] = CallArg(RValue::get(Receiver), ASTIdTy, false);
1470*67e74705SXin Li
1471*67e74705SXin Li imp = EnforceType(Builder, imp, MSI.MessengerType);
1472*67e74705SXin Li
1473*67e74705SXin Li llvm::Instruction *call;
1474*67e74705SXin Li RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
1475*67e74705SXin Li CGCalleeInfo(), &call);
1476*67e74705SXin Li call->setMetadata(msgSendMDKind, node);
1477*67e74705SXin Li
1478*67e74705SXin Li
1479*67e74705SXin Li if (!isPointerSizedReturn) {
1480*67e74705SXin Li messageBB = CGF.Builder.GetInsertBlock();
1481*67e74705SXin Li CGF.Builder.CreateBr(continueBB);
1482*67e74705SXin Li CGF.EmitBlock(continueBB);
1483*67e74705SXin Li if (msgRet.isScalar()) {
1484*67e74705SXin Li llvm::Value *v = msgRet.getScalarVal();
1485*67e74705SXin Li llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1486*67e74705SXin Li phi->addIncoming(v, messageBB);
1487*67e74705SXin Li phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
1488*67e74705SXin Li msgRet = RValue::get(phi);
1489*67e74705SXin Li } else if (msgRet.isAggregate()) {
1490*67e74705SXin Li Address v = msgRet.getAggregateAddress();
1491*67e74705SXin Li llvm::PHINode *phi = Builder.CreatePHI(v.getType(), 2);
1492*67e74705SXin Li llvm::Type *RetTy = v.getElementType();
1493*67e74705SXin Li Address NullVal = CGF.CreateTempAlloca(RetTy, v.getAlignment(), "null");
1494*67e74705SXin Li CGF.InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
1495*67e74705SXin Li phi->addIncoming(v.getPointer(), messageBB);
1496*67e74705SXin Li phi->addIncoming(NullVal.getPointer(), startBB);
1497*67e74705SXin Li msgRet = RValue::getAggregate(Address(phi, v.getAlignment()));
1498*67e74705SXin Li } else /* isComplex() */ {
1499*67e74705SXin Li std::pair<llvm::Value*,llvm::Value*> v = msgRet.getComplexVal();
1500*67e74705SXin Li llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
1501*67e74705SXin Li phi->addIncoming(v.first, messageBB);
1502*67e74705SXin Li phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
1503*67e74705SXin Li startBB);
1504*67e74705SXin Li llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
1505*67e74705SXin Li phi2->addIncoming(v.second, messageBB);
1506*67e74705SXin Li phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
1507*67e74705SXin Li startBB);
1508*67e74705SXin Li msgRet = RValue::getComplex(phi, phi2);
1509*67e74705SXin Li }
1510*67e74705SXin Li }
1511*67e74705SXin Li return msgRet;
1512*67e74705SXin Li }
1513*67e74705SXin Li
1514*67e74705SXin Li /// Generates a MethodList. Used in construction of a objc_class and
1515*67e74705SXin Li /// objc_category structures.
1516*67e74705SXin Li llvm::Constant *CGObjCGNU::
GenerateMethodList(StringRef ClassName,StringRef CategoryName,ArrayRef<Selector> MethodSels,ArrayRef<llvm::Constant * > MethodTypes,bool isClassMethodList)1517*67e74705SXin Li GenerateMethodList(StringRef ClassName,
1518*67e74705SXin Li StringRef CategoryName,
1519*67e74705SXin Li ArrayRef<Selector> MethodSels,
1520*67e74705SXin Li ArrayRef<llvm::Constant *> MethodTypes,
1521*67e74705SXin Li bool isClassMethodList) {
1522*67e74705SXin Li if (MethodSels.empty())
1523*67e74705SXin Li return NULLPtr;
1524*67e74705SXin Li // Get the method structure type.
1525*67e74705SXin Li llvm::StructType *ObjCMethodTy = llvm::StructType::get(
1526*67e74705SXin Li PtrToInt8Ty, // Really a selector, but the runtime creates it us.
1527*67e74705SXin Li PtrToInt8Ty, // Method types
1528*67e74705SXin Li IMPTy, //Method pointer
1529*67e74705SXin Li nullptr);
1530*67e74705SXin Li std::vector<llvm::Constant*> Methods;
1531*67e74705SXin Li for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
1532*67e74705SXin Li llvm::Constant *Method =
1533*67e74705SXin Li TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
1534*67e74705SXin Li MethodSels[i],
1535*67e74705SXin Li isClassMethodList));
1536*67e74705SXin Li assert(Method && "Can't generate metadata for method that doesn't exist");
1537*67e74705SXin Li llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
1538*67e74705SXin Li Method = llvm::ConstantExpr::getBitCast(Method,
1539*67e74705SXin Li IMPTy);
1540*67e74705SXin Li Methods.push_back(
1541*67e74705SXin Li llvm::ConstantStruct::get(ObjCMethodTy, {C, MethodTypes[i], Method}));
1542*67e74705SXin Li }
1543*67e74705SXin Li
1544*67e74705SXin Li // Array of method structures
1545*67e74705SXin Li llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
1546*67e74705SXin Li Methods.size());
1547*67e74705SXin Li llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
1548*67e74705SXin Li Methods);
1549*67e74705SXin Li
1550*67e74705SXin Li // Structure containing list pointer, array and array count
1551*67e74705SXin Li llvm::StructType *ObjCMethodListTy = llvm::StructType::create(VMContext);
1552*67e74705SXin Li llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(ObjCMethodListTy);
1553*67e74705SXin Li ObjCMethodListTy->setBody(
1554*67e74705SXin Li NextPtrTy,
1555*67e74705SXin Li IntTy,
1556*67e74705SXin Li ObjCMethodArrayTy,
1557*67e74705SXin Li nullptr);
1558*67e74705SXin Li
1559*67e74705SXin Li Methods.clear();
1560*67e74705SXin Li Methods.push_back(llvm::ConstantPointerNull::get(
1561*67e74705SXin Li llvm::PointerType::getUnqual(ObjCMethodListTy)));
1562*67e74705SXin Li Methods.push_back(llvm::ConstantInt::get(Int32Ty, MethodTypes.size()));
1563*67e74705SXin Li Methods.push_back(MethodArray);
1564*67e74705SXin Li
1565*67e74705SXin Li // Create an instance of the structure
1566*67e74705SXin Li return MakeGlobal(ObjCMethodListTy, Methods, CGM.getPointerAlign(),
1567*67e74705SXin Li ".objc_method_list");
1568*67e74705SXin Li }
1569*67e74705SXin Li
1570*67e74705SXin Li /// Generates an IvarList. Used in construction of a objc_class.
1571*67e74705SXin Li llvm::Constant *CGObjCGNU::
GenerateIvarList(ArrayRef<llvm::Constant * > IvarNames,ArrayRef<llvm::Constant * > IvarTypes,ArrayRef<llvm::Constant * > IvarOffsets)1572*67e74705SXin Li GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
1573*67e74705SXin Li ArrayRef<llvm::Constant *> IvarTypes,
1574*67e74705SXin Li ArrayRef<llvm::Constant *> IvarOffsets) {
1575*67e74705SXin Li if (IvarNames.size() == 0)
1576*67e74705SXin Li return NULLPtr;
1577*67e74705SXin Li // Get the method structure type.
1578*67e74705SXin Li llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1579*67e74705SXin Li PtrToInt8Ty,
1580*67e74705SXin Li PtrToInt8Ty,
1581*67e74705SXin Li IntTy,
1582*67e74705SXin Li nullptr);
1583*67e74705SXin Li std::vector<llvm::Constant*> Ivars;
1584*67e74705SXin Li for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
1585*67e74705SXin Li Ivars.push_back(llvm::ConstantStruct::get(
1586*67e74705SXin Li ObjCIvarTy, {IvarNames[i], IvarTypes[i], IvarOffsets[i]}));
1587*67e74705SXin Li }
1588*67e74705SXin Li
1589*67e74705SXin Li // Array of method structures
1590*67e74705SXin Li llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
1591*67e74705SXin Li IvarNames.size());
1592*67e74705SXin Li
1593*67e74705SXin Li llvm::Constant *Elements[] = {
1594*67e74705SXin Li llvm::ConstantInt::get(IntTy, (int)IvarNames.size()),
1595*67e74705SXin Li llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)};
1596*67e74705SXin Li // Structure containing array and array count
1597*67e74705SXin Li llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
1598*67e74705SXin Li ObjCIvarArrayTy,
1599*67e74705SXin Li nullptr);
1600*67e74705SXin Li
1601*67e74705SXin Li // Create an instance of the structure
1602*67e74705SXin Li return MakeGlobal(ObjCIvarListTy, Elements, CGM.getPointerAlign(),
1603*67e74705SXin Li ".objc_ivar_list");
1604*67e74705SXin Li }
1605*67e74705SXin Li
1606*67e74705SXin Li /// Generate a class structure
GenerateClassStructure(llvm::Constant * MetaClass,llvm::Constant * SuperClass,unsigned info,const char * Name,llvm::Constant * Version,llvm::Constant * InstanceSize,llvm::Constant * IVars,llvm::Constant * Methods,llvm::Constant * Protocols,llvm::Constant * IvarOffsets,llvm::Constant * Properties,llvm::Constant * StrongIvarBitmap,llvm::Constant * WeakIvarBitmap,bool isMeta)1607*67e74705SXin Li llvm::Constant *CGObjCGNU::GenerateClassStructure(
1608*67e74705SXin Li llvm::Constant *MetaClass,
1609*67e74705SXin Li llvm::Constant *SuperClass,
1610*67e74705SXin Li unsigned info,
1611*67e74705SXin Li const char *Name,
1612*67e74705SXin Li llvm::Constant *Version,
1613*67e74705SXin Li llvm::Constant *InstanceSize,
1614*67e74705SXin Li llvm::Constant *IVars,
1615*67e74705SXin Li llvm::Constant *Methods,
1616*67e74705SXin Li llvm::Constant *Protocols,
1617*67e74705SXin Li llvm::Constant *IvarOffsets,
1618*67e74705SXin Li llvm::Constant *Properties,
1619*67e74705SXin Li llvm::Constant *StrongIvarBitmap,
1620*67e74705SXin Li llvm::Constant *WeakIvarBitmap,
1621*67e74705SXin Li bool isMeta) {
1622*67e74705SXin Li // Set up the class structure
1623*67e74705SXin Li // Note: Several of these are char*s when they should be ids. This is
1624*67e74705SXin Li // because the runtime performs this translation on load.
1625*67e74705SXin Li //
1626*67e74705SXin Li // Fields marked New ABI are part of the GNUstep runtime. We emit them
1627*67e74705SXin Li // anyway; the classes will still work with the GNU runtime, they will just
1628*67e74705SXin Li // be ignored.
1629*67e74705SXin Li llvm::StructType *ClassTy = llvm::StructType::get(
1630*67e74705SXin Li PtrToInt8Ty, // isa
1631*67e74705SXin Li PtrToInt8Ty, // super_class
1632*67e74705SXin Li PtrToInt8Ty, // name
1633*67e74705SXin Li LongTy, // version
1634*67e74705SXin Li LongTy, // info
1635*67e74705SXin Li LongTy, // instance_size
1636*67e74705SXin Li IVars->getType(), // ivars
1637*67e74705SXin Li Methods->getType(), // methods
1638*67e74705SXin Li // These are all filled in by the runtime, so we pretend
1639*67e74705SXin Li PtrTy, // dtable
1640*67e74705SXin Li PtrTy, // subclass_list
1641*67e74705SXin Li PtrTy, // sibling_class
1642*67e74705SXin Li PtrTy, // protocols
1643*67e74705SXin Li PtrTy, // gc_object_type
1644*67e74705SXin Li // New ABI:
1645*67e74705SXin Li LongTy, // abi_version
1646*67e74705SXin Li IvarOffsets->getType(), // ivar_offsets
1647*67e74705SXin Li Properties->getType(), // properties
1648*67e74705SXin Li IntPtrTy, // strong_pointers
1649*67e74705SXin Li IntPtrTy, // weak_pointers
1650*67e74705SXin Li nullptr);
1651*67e74705SXin Li llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
1652*67e74705SXin Li // Fill in the structure
1653*67e74705SXin Li std::vector<llvm::Constant*> Elements;
1654*67e74705SXin Li Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
1655*67e74705SXin Li Elements.push_back(SuperClass);
1656*67e74705SXin Li Elements.push_back(MakeConstantString(Name, ".class_name"));
1657*67e74705SXin Li Elements.push_back(Zero);
1658*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(LongTy, info));
1659*67e74705SXin Li if (isMeta) {
1660*67e74705SXin Li llvm::DataLayout td(&TheModule);
1661*67e74705SXin Li Elements.push_back(
1662*67e74705SXin Li llvm::ConstantInt::get(LongTy,
1663*67e74705SXin Li td.getTypeSizeInBits(ClassTy) /
1664*67e74705SXin Li CGM.getContext().getCharWidth()));
1665*67e74705SXin Li } else
1666*67e74705SXin Li Elements.push_back(InstanceSize);
1667*67e74705SXin Li Elements.push_back(IVars);
1668*67e74705SXin Li Elements.push_back(Methods);
1669*67e74705SXin Li Elements.push_back(NULLPtr);
1670*67e74705SXin Li Elements.push_back(NULLPtr);
1671*67e74705SXin Li Elements.push_back(NULLPtr);
1672*67e74705SXin Li Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
1673*67e74705SXin Li Elements.push_back(NULLPtr);
1674*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(LongTy, 1));
1675*67e74705SXin Li Elements.push_back(IvarOffsets);
1676*67e74705SXin Li Elements.push_back(Properties);
1677*67e74705SXin Li Elements.push_back(StrongIvarBitmap);
1678*67e74705SXin Li Elements.push_back(WeakIvarBitmap);
1679*67e74705SXin Li // Create an instance of the structure
1680*67e74705SXin Li // This is now an externally visible symbol, so that we can speed up class
1681*67e74705SXin Li // messages in the next ABI. We may already have some weak references to
1682*67e74705SXin Li // this, so check and fix them properly.
1683*67e74705SXin Li std::string ClassSym((isMeta ? "_OBJC_METACLASS_": "_OBJC_CLASS_") +
1684*67e74705SXin Li std::string(Name));
1685*67e74705SXin Li llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
1686*67e74705SXin Li llvm::Constant *Class =
1687*67e74705SXin Li MakeGlobal(ClassTy, Elements, CGM.getPointerAlign(), ClassSym,
1688*67e74705SXin Li llvm::GlobalValue::ExternalLinkage);
1689*67e74705SXin Li if (ClassRef) {
1690*67e74705SXin Li ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
1691*67e74705SXin Li ClassRef->getType()));
1692*67e74705SXin Li ClassRef->removeFromParent();
1693*67e74705SXin Li Class->setName(ClassSym);
1694*67e74705SXin Li }
1695*67e74705SXin Li return Class;
1696*67e74705SXin Li }
1697*67e74705SXin Li
1698*67e74705SXin Li llvm::Constant *CGObjCGNU::
GenerateProtocolMethodList(ArrayRef<llvm::Constant * > MethodNames,ArrayRef<llvm::Constant * > MethodTypes)1699*67e74705SXin Li GenerateProtocolMethodList(ArrayRef<llvm::Constant *> MethodNames,
1700*67e74705SXin Li ArrayRef<llvm::Constant *> MethodTypes) {
1701*67e74705SXin Li // Get the method structure type.
1702*67e74705SXin Li llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
1703*67e74705SXin Li PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
1704*67e74705SXin Li PtrToInt8Ty,
1705*67e74705SXin Li nullptr);
1706*67e74705SXin Li std::vector<llvm::Constant*> Methods;
1707*67e74705SXin Li for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
1708*67e74705SXin Li Methods.push_back(llvm::ConstantStruct::get(
1709*67e74705SXin Li ObjCMethodDescTy, {MethodNames[i], MethodTypes[i]}));
1710*67e74705SXin Li }
1711*67e74705SXin Li llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
1712*67e74705SXin Li MethodNames.size());
1713*67e74705SXin Li llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
1714*67e74705SXin Li Methods);
1715*67e74705SXin Li llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
1716*67e74705SXin Li IntTy, ObjCMethodArrayTy, nullptr);
1717*67e74705SXin Li Methods.clear();
1718*67e74705SXin Li Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
1719*67e74705SXin Li Methods.push_back(Array);
1720*67e74705SXin Li return MakeGlobal(ObjCMethodDescListTy, Methods, CGM.getPointerAlign(),
1721*67e74705SXin Li ".objc_method_list");
1722*67e74705SXin Li }
1723*67e74705SXin Li
1724*67e74705SXin Li // Create the protocol list structure used in classes, categories and so on
GenerateProtocolList(ArrayRef<std::string> Protocols)1725*67e74705SXin Li llvm::Constant *CGObjCGNU::GenerateProtocolList(ArrayRef<std::string>Protocols){
1726*67e74705SXin Li llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
1727*67e74705SXin Li Protocols.size());
1728*67e74705SXin Li llvm::StructType *ProtocolListTy = llvm::StructType::get(
1729*67e74705SXin Li PtrTy, //Should be a recurisve pointer, but it's always NULL here.
1730*67e74705SXin Li SizeTy,
1731*67e74705SXin Li ProtocolArrayTy,
1732*67e74705SXin Li nullptr);
1733*67e74705SXin Li std::vector<llvm::Constant*> Elements;
1734*67e74705SXin Li for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
1735*67e74705SXin Li iter != endIter ; iter++) {
1736*67e74705SXin Li llvm::Constant *protocol = nullptr;
1737*67e74705SXin Li llvm::StringMap<llvm::Constant*>::iterator value =
1738*67e74705SXin Li ExistingProtocols.find(*iter);
1739*67e74705SXin Li if (value == ExistingProtocols.end()) {
1740*67e74705SXin Li protocol = GenerateEmptyProtocol(*iter);
1741*67e74705SXin Li } else {
1742*67e74705SXin Li protocol = value->getValue();
1743*67e74705SXin Li }
1744*67e74705SXin Li llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
1745*67e74705SXin Li PtrToInt8Ty);
1746*67e74705SXin Li Elements.push_back(Ptr);
1747*67e74705SXin Li }
1748*67e74705SXin Li llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1749*67e74705SXin Li Elements);
1750*67e74705SXin Li Elements.clear();
1751*67e74705SXin Li Elements.push_back(NULLPtr);
1752*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
1753*67e74705SXin Li Elements.push_back(ProtocolArray);
1754*67e74705SXin Li return MakeGlobal(ProtocolListTy, Elements, CGM.getPointerAlign(),
1755*67e74705SXin Li ".objc_protocol_list");
1756*67e74705SXin Li }
1757*67e74705SXin Li
GenerateProtocolRef(CodeGenFunction & CGF,const ObjCProtocolDecl * PD)1758*67e74705SXin Li llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF,
1759*67e74705SXin Li const ObjCProtocolDecl *PD) {
1760*67e74705SXin Li llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
1761*67e74705SXin Li llvm::Type *T =
1762*67e74705SXin Li CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
1763*67e74705SXin Li return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
1764*67e74705SXin Li }
1765*67e74705SXin Li
GenerateEmptyProtocol(const std::string & ProtocolName)1766*67e74705SXin Li llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
1767*67e74705SXin Li const std::string &ProtocolName) {
1768*67e74705SXin Li SmallVector<std::string, 0> EmptyStringVector;
1769*67e74705SXin Li SmallVector<llvm::Constant*, 0> EmptyConstantVector;
1770*67e74705SXin Li
1771*67e74705SXin Li llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
1772*67e74705SXin Li llvm::Constant *MethodList =
1773*67e74705SXin Li GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
1774*67e74705SXin Li // Protocols are objects containing lists of the methods implemented and
1775*67e74705SXin Li // protocols adopted.
1776*67e74705SXin Li llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1777*67e74705SXin Li PtrToInt8Ty,
1778*67e74705SXin Li ProtocolList->getType(),
1779*67e74705SXin Li MethodList->getType(),
1780*67e74705SXin Li MethodList->getType(),
1781*67e74705SXin Li MethodList->getType(),
1782*67e74705SXin Li MethodList->getType(),
1783*67e74705SXin Li nullptr);
1784*67e74705SXin Li // The isa pointer must be set to a magic number so the runtime knows it's
1785*67e74705SXin Li // the correct layout.
1786*67e74705SXin Li llvm::Constant *Elements[] = {
1787*67e74705SXin Li llvm::ConstantExpr::getIntToPtr(
1788*67e74705SXin Li llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy),
1789*67e74705SXin Li MakeConstantString(ProtocolName, ".objc_protocol_name"), ProtocolList,
1790*67e74705SXin Li MethodList, MethodList, MethodList, MethodList};
1791*67e74705SXin Li return MakeGlobal(ProtocolTy, Elements, CGM.getPointerAlign(),
1792*67e74705SXin Li ".objc_protocol");
1793*67e74705SXin Li }
1794*67e74705SXin Li
GenerateProtocol(const ObjCProtocolDecl * PD)1795*67e74705SXin Li void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
1796*67e74705SXin Li ASTContext &Context = CGM.getContext();
1797*67e74705SXin Li std::string ProtocolName = PD->getNameAsString();
1798*67e74705SXin Li
1799*67e74705SXin Li // Use the protocol definition, if there is one.
1800*67e74705SXin Li if (const ObjCProtocolDecl *Def = PD->getDefinition())
1801*67e74705SXin Li PD = Def;
1802*67e74705SXin Li
1803*67e74705SXin Li SmallVector<std::string, 16> Protocols;
1804*67e74705SXin Li for (const auto *PI : PD->protocols())
1805*67e74705SXin Li Protocols.push_back(PI->getNameAsString());
1806*67e74705SXin Li SmallVector<llvm::Constant*, 16> InstanceMethodNames;
1807*67e74705SXin Li SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
1808*67e74705SXin Li SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames;
1809*67e74705SXin Li SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes;
1810*67e74705SXin Li for (const auto *I : PD->instance_methods()) {
1811*67e74705SXin Li std::string TypeStr;
1812*67e74705SXin Li Context.getObjCEncodingForMethodDecl(I, TypeStr);
1813*67e74705SXin Li if (I->getImplementationControl() == ObjCMethodDecl::Optional) {
1814*67e74705SXin Li OptionalInstanceMethodNames.push_back(
1815*67e74705SXin Li MakeConstantString(I->getSelector().getAsString()));
1816*67e74705SXin Li OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1817*67e74705SXin Li } else {
1818*67e74705SXin Li InstanceMethodNames.push_back(
1819*67e74705SXin Li MakeConstantString(I->getSelector().getAsString()));
1820*67e74705SXin Li InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1821*67e74705SXin Li }
1822*67e74705SXin Li }
1823*67e74705SXin Li // Collect information about class methods:
1824*67e74705SXin Li SmallVector<llvm::Constant*, 16> ClassMethodNames;
1825*67e74705SXin Li SmallVector<llvm::Constant*, 16> ClassMethodTypes;
1826*67e74705SXin Li SmallVector<llvm::Constant*, 16> OptionalClassMethodNames;
1827*67e74705SXin Li SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes;
1828*67e74705SXin Li for (const auto *I : PD->class_methods()) {
1829*67e74705SXin Li std::string TypeStr;
1830*67e74705SXin Li Context.getObjCEncodingForMethodDecl(I,TypeStr);
1831*67e74705SXin Li if (I->getImplementationControl() == ObjCMethodDecl::Optional) {
1832*67e74705SXin Li OptionalClassMethodNames.push_back(
1833*67e74705SXin Li MakeConstantString(I->getSelector().getAsString()));
1834*67e74705SXin Li OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1835*67e74705SXin Li } else {
1836*67e74705SXin Li ClassMethodNames.push_back(
1837*67e74705SXin Li MakeConstantString(I->getSelector().getAsString()));
1838*67e74705SXin Li ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1839*67e74705SXin Li }
1840*67e74705SXin Li }
1841*67e74705SXin Li
1842*67e74705SXin Li llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1843*67e74705SXin Li llvm::Constant *InstanceMethodList =
1844*67e74705SXin Li GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1845*67e74705SXin Li llvm::Constant *ClassMethodList =
1846*67e74705SXin Li GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1847*67e74705SXin Li llvm::Constant *OptionalInstanceMethodList =
1848*67e74705SXin Li GenerateProtocolMethodList(OptionalInstanceMethodNames,
1849*67e74705SXin Li OptionalInstanceMethodTypes);
1850*67e74705SXin Li llvm::Constant *OptionalClassMethodList =
1851*67e74705SXin Li GenerateProtocolMethodList(OptionalClassMethodNames,
1852*67e74705SXin Li OptionalClassMethodTypes);
1853*67e74705SXin Li
1854*67e74705SXin Li // Property metadata: name, attributes, isSynthesized, setter name, setter
1855*67e74705SXin Li // types, getter name, getter types.
1856*67e74705SXin Li // The isSynthesized value is always set to 0 in a protocol. It exists to
1857*67e74705SXin Li // simplify the runtime library by allowing it to use the same data
1858*67e74705SXin Li // structures for protocol metadata everywhere.
1859*67e74705SXin Li llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
1860*67e74705SXin Li PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
1861*67e74705SXin Li PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);
1862*67e74705SXin Li std::vector<llvm::Constant*> Properties;
1863*67e74705SXin Li std::vector<llvm::Constant*> OptionalProperties;
1864*67e74705SXin Li
1865*67e74705SXin Li // Add all of the property methods need adding to the method list and to the
1866*67e74705SXin Li // property metadata list.
1867*67e74705SXin Li for (auto *property : PD->instance_properties()) {
1868*67e74705SXin Li std::vector<llvm::Constant*> Fields;
1869*67e74705SXin Li
1870*67e74705SXin Li Fields.push_back(MakePropertyEncodingString(property, nullptr));
1871*67e74705SXin Li PushPropertyAttributes(Fields, property);
1872*67e74705SXin Li
1873*67e74705SXin Li if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
1874*67e74705SXin Li std::string TypeStr;
1875*67e74705SXin Li Context.getObjCEncodingForMethodDecl(getter,TypeStr);
1876*67e74705SXin Li llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1877*67e74705SXin Li InstanceMethodTypes.push_back(TypeEncoding);
1878*67e74705SXin Li Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1879*67e74705SXin Li Fields.push_back(TypeEncoding);
1880*67e74705SXin Li } else {
1881*67e74705SXin Li Fields.push_back(NULLPtr);
1882*67e74705SXin Li Fields.push_back(NULLPtr);
1883*67e74705SXin Li }
1884*67e74705SXin Li if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
1885*67e74705SXin Li std::string TypeStr;
1886*67e74705SXin Li Context.getObjCEncodingForMethodDecl(setter,TypeStr);
1887*67e74705SXin Li llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1888*67e74705SXin Li InstanceMethodTypes.push_back(TypeEncoding);
1889*67e74705SXin Li Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1890*67e74705SXin Li Fields.push_back(TypeEncoding);
1891*67e74705SXin Li } else {
1892*67e74705SXin Li Fields.push_back(NULLPtr);
1893*67e74705SXin Li Fields.push_back(NULLPtr);
1894*67e74705SXin Li }
1895*67e74705SXin Li if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
1896*67e74705SXin Li OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1897*67e74705SXin Li } else {
1898*67e74705SXin Li Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1899*67e74705SXin Li }
1900*67e74705SXin Li }
1901*67e74705SXin Li llvm::Constant *PropertyArray = llvm::ConstantArray::get(
1902*67e74705SXin Li llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
1903*67e74705SXin Li llvm::Constant* PropertyListInitFields[] =
1904*67e74705SXin Li {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1905*67e74705SXin Li
1906*67e74705SXin Li llvm::Constant *PropertyListInit =
1907*67e74705SXin Li llvm::ConstantStruct::getAnon(PropertyListInitFields);
1908*67e74705SXin Li llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule,
1909*67e74705SXin Li PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage,
1910*67e74705SXin Li PropertyListInit, ".objc_property_list");
1911*67e74705SXin Li
1912*67e74705SXin Li llvm::Constant *OptionalPropertyArray =
1913*67e74705SXin Li llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
1914*67e74705SXin Li OptionalProperties.size()) , OptionalProperties);
1915*67e74705SXin Li llvm::Constant* OptionalPropertyListInitFields[] = {
1916*67e74705SXin Li llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
1917*67e74705SXin Li OptionalPropertyArray };
1918*67e74705SXin Li
1919*67e74705SXin Li llvm::Constant *OptionalPropertyListInit =
1920*67e74705SXin Li llvm::ConstantStruct::getAnon(OptionalPropertyListInitFields);
1921*67e74705SXin Li llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule,
1922*67e74705SXin Li OptionalPropertyListInit->getType(), false,
1923*67e74705SXin Li llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit,
1924*67e74705SXin Li ".objc_property_list");
1925*67e74705SXin Li
1926*67e74705SXin Li // Protocols are objects containing lists of the methods implemented and
1927*67e74705SXin Li // protocols adopted.
1928*67e74705SXin Li llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1929*67e74705SXin Li PtrToInt8Ty,
1930*67e74705SXin Li ProtocolList->getType(),
1931*67e74705SXin Li InstanceMethodList->getType(),
1932*67e74705SXin Li ClassMethodList->getType(),
1933*67e74705SXin Li OptionalInstanceMethodList->getType(),
1934*67e74705SXin Li OptionalClassMethodList->getType(),
1935*67e74705SXin Li PropertyList->getType(),
1936*67e74705SXin Li OptionalPropertyList->getType(),
1937*67e74705SXin Li nullptr);
1938*67e74705SXin Li // The isa pointer must be set to a magic number so the runtime knows it's
1939*67e74705SXin Li // the correct layout.
1940*67e74705SXin Li llvm::Constant *Elements[] = {
1941*67e74705SXin Li llvm::ConstantExpr::getIntToPtr(
1942*67e74705SXin Li llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy),
1943*67e74705SXin Li MakeConstantString(ProtocolName, ".objc_protocol_name"), ProtocolList,
1944*67e74705SXin Li InstanceMethodList, ClassMethodList, OptionalInstanceMethodList,
1945*67e74705SXin Li OptionalClassMethodList, PropertyList, OptionalPropertyList};
1946*67e74705SXin Li ExistingProtocols[ProtocolName] =
1947*67e74705SXin Li llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
1948*67e74705SXin Li CGM.getPointerAlign(), ".objc_protocol"), IdTy);
1949*67e74705SXin Li }
GenerateProtocolHolderCategory()1950*67e74705SXin Li void CGObjCGNU::GenerateProtocolHolderCategory() {
1951*67e74705SXin Li // Collect information about instance methods
1952*67e74705SXin Li SmallVector<Selector, 1> MethodSels;
1953*67e74705SXin Li SmallVector<llvm::Constant*, 1> MethodTypes;
1954*67e74705SXin Li
1955*67e74705SXin Li std::vector<llvm::Constant*> Elements;
1956*67e74705SXin Li const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
1957*67e74705SXin Li const std::string CategoryName = "AnotherHack";
1958*67e74705SXin Li Elements.push_back(MakeConstantString(CategoryName));
1959*67e74705SXin Li Elements.push_back(MakeConstantString(ClassName));
1960*67e74705SXin Li // Instance method list
1961*67e74705SXin Li Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1962*67e74705SXin Li ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));
1963*67e74705SXin Li // Class method list
1964*67e74705SXin Li Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1965*67e74705SXin Li ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));
1966*67e74705SXin Li // Protocol list
1967*67e74705SXin Li llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
1968*67e74705SXin Li ExistingProtocols.size());
1969*67e74705SXin Li llvm::StructType *ProtocolListTy = llvm::StructType::get(
1970*67e74705SXin Li PtrTy, //Should be a recurisve pointer, but it's always NULL here.
1971*67e74705SXin Li SizeTy,
1972*67e74705SXin Li ProtocolArrayTy,
1973*67e74705SXin Li nullptr);
1974*67e74705SXin Li std::vector<llvm::Constant*> ProtocolElements;
1975*67e74705SXin Li for (llvm::StringMapIterator<llvm::Constant*> iter =
1976*67e74705SXin Li ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1977*67e74705SXin Li iter != endIter ; iter++) {
1978*67e74705SXin Li llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
1979*67e74705SXin Li PtrTy);
1980*67e74705SXin Li ProtocolElements.push_back(Ptr);
1981*67e74705SXin Li }
1982*67e74705SXin Li llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1983*67e74705SXin Li ProtocolElements);
1984*67e74705SXin Li ProtocolElements.clear();
1985*67e74705SXin Li ProtocolElements.push_back(NULLPtr);
1986*67e74705SXin Li ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
1987*67e74705SXin Li ExistingProtocols.size()));
1988*67e74705SXin Li ProtocolElements.push_back(ProtocolArray);
1989*67e74705SXin Li Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
1990*67e74705SXin Li ProtocolElements, CGM.getPointerAlign(),
1991*67e74705SXin Li ".objc_protocol_list"), PtrTy));
1992*67e74705SXin Li Categories.push_back(llvm::ConstantExpr::getBitCast(
1993*67e74705SXin Li MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
1994*67e74705SXin Li PtrTy, PtrTy, PtrTy, nullptr), Elements, CGM.getPointerAlign()),
1995*67e74705SXin Li PtrTy));
1996*67e74705SXin Li }
1997*67e74705SXin Li
1998*67e74705SXin Li /// Libobjc2 uses a bitfield representation where small(ish) bitfields are
1999*67e74705SXin Li /// stored in a 64-bit value with the low bit set to 1 and the remaining 63
2000*67e74705SXin Li /// bits set to their values, LSB first, while larger ones are stored in a
2001*67e74705SXin Li /// structure of this / form:
2002*67e74705SXin Li ///
2003*67e74705SXin Li /// struct { int32_t length; int32_t values[length]; };
2004*67e74705SXin Li ///
2005*67e74705SXin Li /// The values in the array are stored in host-endian format, with the least
2006*67e74705SXin Li /// significant bit being assumed to come first in the bitfield. Therefore, a
2007*67e74705SXin Li /// bitfield with the 64th bit set will be (int64_t)&{ 2, [0, 1<<31] }, while a
2008*67e74705SXin Li /// bitfield / with the 63rd bit set will be 1<<64.
MakeBitField(ArrayRef<bool> bits)2009*67e74705SXin Li llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) {
2010*67e74705SXin Li int bitCount = bits.size();
2011*67e74705SXin Li int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
2012*67e74705SXin Li if (bitCount < ptrBits) {
2013*67e74705SXin Li uint64_t val = 1;
2014*67e74705SXin Li for (int i=0 ; i<bitCount ; ++i) {
2015*67e74705SXin Li if (bits[i]) val |= 1ULL<<(i+1);
2016*67e74705SXin Li }
2017*67e74705SXin Li return llvm::ConstantInt::get(IntPtrTy, val);
2018*67e74705SXin Li }
2019*67e74705SXin Li SmallVector<llvm::Constant *, 8> values;
2020*67e74705SXin Li int v=0;
2021*67e74705SXin Li while (v < bitCount) {
2022*67e74705SXin Li int32_t word = 0;
2023*67e74705SXin Li for (int i=0 ; (i<32) && (v<bitCount) ; ++i) {
2024*67e74705SXin Li if (bits[v]) word |= 1<<i;
2025*67e74705SXin Li v++;
2026*67e74705SXin Li }
2027*67e74705SXin Li values.push_back(llvm::ConstantInt::get(Int32Ty, word));
2028*67e74705SXin Li }
2029*67e74705SXin Li llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());
2030*67e74705SXin Li llvm::Constant *array = llvm::ConstantArray::get(arrayTy, values);
2031*67e74705SXin Li llvm::Constant *fields[2] = {
2032*67e74705SXin Li llvm::ConstantInt::get(Int32Ty, values.size()),
2033*67e74705SXin Li array };
2034*67e74705SXin Li llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
2035*67e74705SXin Li nullptr), fields, CharUnits::fromQuantity(4));
2036*67e74705SXin Li llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
2037*67e74705SXin Li return ptr;
2038*67e74705SXin Li }
2039*67e74705SXin Li
GenerateCategory(const ObjCCategoryImplDecl * OCD)2040*67e74705SXin Li void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2041*67e74705SXin Li std::string ClassName = OCD->getClassInterface()->getNameAsString();
2042*67e74705SXin Li std::string CategoryName = OCD->getNameAsString();
2043*67e74705SXin Li // Collect information about instance methods
2044*67e74705SXin Li SmallVector<Selector, 16> InstanceMethodSels;
2045*67e74705SXin Li SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
2046*67e74705SXin Li for (const auto *I : OCD->instance_methods()) {
2047*67e74705SXin Li InstanceMethodSels.push_back(I->getSelector());
2048*67e74705SXin Li std::string TypeStr;
2049*67e74705SXin Li CGM.getContext().getObjCEncodingForMethodDecl(I,TypeStr);
2050*67e74705SXin Li InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2051*67e74705SXin Li }
2052*67e74705SXin Li
2053*67e74705SXin Li // Collect information about class methods
2054*67e74705SXin Li SmallVector<Selector, 16> ClassMethodSels;
2055*67e74705SXin Li SmallVector<llvm::Constant*, 16> ClassMethodTypes;
2056*67e74705SXin Li for (const auto *I : OCD->class_methods()) {
2057*67e74705SXin Li ClassMethodSels.push_back(I->getSelector());
2058*67e74705SXin Li std::string TypeStr;
2059*67e74705SXin Li CGM.getContext().getObjCEncodingForMethodDecl(I,TypeStr);
2060*67e74705SXin Li ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2061*67e74705SXin Li }
2062*67e74705SXin Li
2063*67e74705SXin Li // Collect the names of referenced protocols
2064*67e74705SXin Li SmallVector<std::string, 16> Protocols;
2065*67e74705SXin Li const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
2066*67e74705SXin Li const ObjCList<ObjCProtocolDecl> &Protos = CatDecl->getReferencedProtocols();
2067*67e74705SXin Li for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
2068*67e74705SXin Li E = Protos.end(); I != E; ++I)
2069*67e74705SXin Li Protocols.push_back((*I)->getNameAsString());
2070*67e74705SXin Li
2071*67e74705SXin Li llvm::Constant *Elements[] = {
2072*67e74705SXin Li MakeConstantString(CategoryName), MakeConstantString(ClassName),
2073*67e74705SXin Li // Instance method list
2074*67e74705SXin Li llvm::ConstantExpr::getBitCast(
2075*67e74705SXin Li GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,
2076*67e74705SXin Li InstanceMethodTypes, false),
2077*67e74705SXin Li PtrTy),
2078*67e74705SXin Li // Class method list
2079*67e74705SXin Li llvm::ConstantExpr::getBitCast(GenerateMethodList(ClassName, CategoryName,
2080*67e74705SXin Li ClassMethodSels,
2081*67e74705SXin Li ClassMethodTypes, true),
2082*67e74705SXin Li PtrTy),
2083*67e74705SXin Li // Protocol list
2084*67e74705SXin Li llvm::ConstantExpr::getBitCast(GenerateProtocolList(Protocols), PtrTy)};
2085*67e74705SXin Li Categories.push_back(llvm::ConstantExpr::getBitCast(
2086*67e74705SXin Li MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
2087*67e74705SXin Li PtrTy, PtrTy, PtrTy, nullptr), Elements, CGM.getPointerAlign()),
2088*67e74705SXin Li PtrTy));
2089*67e74705SXin Li }
2090*67e74705SXin Li
GeneratePropertyList(const ObjCImplementationDecl * OID,SmallVectorImpl<Selector> & InstanceMethodSels,SmallVectorImpl<llvm::Constant * > & InstanceMethodTypes)2091*67e74705SXin Li llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID,
2092*67e74705SXin Li SmallVectorImpl<Selector> &InstanceMethodSels,
2093*67e74705SXin Li SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) {
2094*67e74705SXin Li ASTContext &Context = CGM.getContext();
2095*67e74705SXin Li // Property metadata: name, attributes, attributes2, padding1, padding2,
2096*67e74705SXin Li // setter name, setter types, getter name, getter types.
2097*67e74705SXin Li llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
2098*67e74705SXin Li PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
2099*67e74705SXin Li PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);
2100*67e74705SXin Li std::vector<llvm::Constant*> Properties;
2101*67e74705SXin Li
2102*67e74705SXin Li // Add all of the property methods need adding to the method list and to the
2103*67e74705SXin Li // property metadata list.
2104*67e74705SXin Li for (auto *propertyImpl : OID->property_impls()) {
2105*67e74705SXin Li std::vector<llvm::Constant*> Fields;
2106*67e74705SXin Li ObjCPropertyDecl *property = propertyImpl->getPropertyDecl();
2107*67e74705SXin Li bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
2108*67e74705SXin Li ObjCPropertyImplDecl::Synthesize);
2109*67e74705SXin Li bool isDynamic = (propertyImpl->getPropertyImplementation() ==
2110*67e74705SXin Li ObjCPropertyImplDecl::Dynamic);
2111*67e74705SXin Li
2112*67e74705SXin Li Fields.push_back(MakePropertyEncodingString(property, OID));
2113*67e74705SXin Li PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
2114*67e74705SXin Li if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
2115*67e74705SXin Li std::string TypeStr;
2116*67e74705SXin Li Context.getObjCEncodingForMethodDecl(getter,TypeStr);
2117*67e74705SXin Li llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2118*67e74705SXin Li if (isSynthesized) {
2119*67e74705SXin Li InstanceMethodTypes.push_back(TypeEncoding);
2120*67e74705SXin Li InstanceMethodSels.push_back(getter->getSelector());
2121*67e74705SXin Li }
2122*67e74705SXin Li Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
2123*67e74705SXin Li Fields.push_back(TypeEncoding);
2124*67e74705SXin Li } else {
2125*67e74705SXin Li Fields.push_back(NULLPtr);
2126*67e74705SXin Li Fields.push_back(NULLPtr);
2127*67e74705SXin Li }
2128*67e74705SXin Li if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
2129*67e74705SXin Li std::string TypeStr;
2130*67e74705SXin Li Context.getObjCEncodingForMethodDecl(setter,TypeStr);
2131*67e74705SXin Li llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2132*67e74705SXin Li if (isSynthesized) {
2133*67e74705SXin Li InstanceMethodTypes.push_back(TypeEncoding);
2134*67e74705SXin Li InstanceMethodSels.push_back(setter->getSelector());
2135*67e74705SXin Li }
2136*67e74705SXin Li Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
2137*67e74705SXin Li Fields.push_back(TypeEncoding);
2138*67e74705SXin Li } else {
2139*67e74705SXin Li Fields.push_back(NULLPtr);
2140*67e74705SXin Li Fields.push_back(NULLPtr);
2141*67e74705SXin Li }
2142*67e74705SXin Li Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
2143*67e74705SXin Li }
2144*67e74705SXin Li llvm::ArrayType *PropertyArrayTy =
2145*67e74705SXin Li llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
2146*67e74705SXin Li llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
2147*67e74705SXin Li Properties);
2148*67e74705SXin Li llvm::Constant* PropertyListInitFields[] =
2149*67e74705SXin Li {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
2150*67e74705SXin Li
2151*67e74705SXin Li llvm::Constant *PropertyListInit =
2152*67e74705SXin Li llvm::ConstantStruct::getAnon(PropertyListInitFields);
2153*67e74705SXin Li return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false,
2154*67e74705SXin Li llvm::GlobalValue::InternalLinkage, PropertyListInit,
2155*67e74705SXin Li ".objc_property_list");
2156*67e74705SXin Li }
2157*67e74705SXin Li
RegisterAlias(const ObjCCompatibleAliasDecl * OAD)2158*67e74705SXin Li void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {
2159*67e74705SXin Li // Get the class declaration for which the alias is specified.
2160*67e74705SXin Li ObjCInterfaceDecl *ClassDecl =
2161*67e74705SXin Li const_cast<ObjCInterfaceDecl *>(OAD->getClassInterface());
2162*67e74705SXin Li ClassAliases.emplace_back(ClassDecl->getNameAsString(),
2163*67e74705SXin Li OAD->getNameAsString());
2164*67e74705SXin Li }
2165*67e74705SXin Li
GenerateClass(const ObjCImplementationDecl * OID)2166*67e74705SXin Li void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
2167*67e74705SXin Li ASTContext &Context = CGM.getContext();
2168*67e74705SXin Li
2169*67e74705SXin Li // Get the superclass name.
2170*67e74705SXin Li const ObjCInterfaceDecl * SuperClassDecl =
2171*67e74705SXin Li OID->getClassInterface()->getSuperClass();
2172*67e74705SXin Li std::string SuperClassName;
2173*67e74705SXin Li if (SuperClassDecl) {
2174*67e74705SXin Li SuperClassName = SuperClassDecl->getNameAsString();
2175*67e74705SXin Li EmitClassRef(SuperClassName);
2176*67e74705SXin Li }
2177*67e74705SXin Li
2178*67e74705SXin Li // Get the class name
2179*67e74705SXin Li ObjCInterfaceDecl *ClassDecl =
2180*67e74705SXin Li const_cast<ObjCInterfaceDecl *>(OID->getClassInterface());
2181*67e74705SXin Li std::string ClassName = ClassDecl->getNameAsString();
2182*67e74705SXin Li // Emit the symbol that is used to generate linker errors if this class is
2183*67e74705SXin Li // referenced in other modules but not declared.
2184*67e74705SXin Li std::string classSymbolName = "__objc_class_name_" + ClassName;
2185*67e74705SXin Li if (llvm::GlobalVariable *symbol =
2186*67e74705SXin Li TheModule.getGlobalVariable(classSymbolName)) {
2187*67e74705SXin Li symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
2188*67e74705SXin Li } else {
2189*67e74705SXin Li new llvm::GlobalVariable(TheModule, LongTy, false,
2190*67e74705SXin Li llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0),
2191*67e74705SXin Li classSymbolName);
2192*67e74705SXin Li }
2193*67e74705SXin Li
2194*67e74705SXin Li // Get the size of instances.
2195*67e74705SXin Li int instanceSize =
2196*67e74705SXin Li Context.getASTObjCImplementationLayout(OID).getSize().getQuantity();
2197*67e74705SXin Li
2198*67e74705SXin Li // Collect information about instance variables.
2199*67e74705SXin Li SmallVector<llvm::Constant*, 16> IvarNames;
2200*67e74705SXin Li SmallVector<llvm::Constant*, 16> IvarTypes;
2201*67e74705SXin Li SmallVector<llvm::Constant*, 16> IvarOffsets;
2202*67e74705SXin Li
2203*67e74705SXin Li std::vector<llvm::Constant*> IvarOffsetValues;
2204*67e74705SXin Li SmallVector<bool, 16> WeakIvars;
2205*67e74705SXin Li SmallVector<bool, 16> StrongIvars;
2206*67e74705SXin Li
2207*67e74705SXin Li int superInstanceSize = !SuperClassDecl ? 0 :
2208*67e74705SXin Li Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity();
2209*67e74705SXin Li // For non-fragile ivars, set the instance size to 0 - {the size of just this
2210*67e74705SXin Li // class}. The runtime will then set this to the correct value on load.
2211*67e74705SXin Li if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2212*67e74705SXin Li instanceSize = 0 - (instanceSize - superInstanceSize);
2213*67e74705SXin Li }
2214*67e74705SXin Li
2215*67e74705SXin Li for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD;
2216*67e74705SXin Li IVD = IVD->getNextIvar()) {
2217*67e74705SXin Li // Store the name
2218*67e74705SXin Li IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
2219*67e74705SXin Li // Get the type encoding for this ivar
2220*67e74705SXin Li std::string TypeStr;
2221*67e74705SXin Li Context.getObjCEncodingForType(IVD->getType(), TypeStr);
2222*67e74705SXin Li IvarTypes.push_back(MakeConstantString(TypeStr));
2223*67e74705SXin Li // Get the offset
2224*67e74705SXin Li uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
2225*67e74705SXin Li uint64_t Offset = BaseOffset;
2226*67e74705SXin Li if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2227*67e74705SXin Li Offset = BaseOffset - superInstanceSize;
2228*67e74705SXin Li }
2229*67e74705SXin Li llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
2230*67e74705SXin Li // Create the direct offset value
2231*67e74705SXin Li std::string OffsetName = "__objc_ivar_offset_value_" + ClassName +"." +
2232*67e74705SXin Li IVD->getNameAsString();
2233*67e74705SXin Li llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
2234*67e74705SXin Li if (OffsetVar) {
2235*67e74705SXin Li OffsetVar->setInitializer(OffsetValue);
2236*67e74705SXin Li // If this is the real definition, change its linkage type so that
2237*67e74705SXin Li // different modules will use this one, rather than their private
2238*67e74705SXin Li // copy.
2239*67e74705SXin Li OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
2240*67e74705SXin Li } else
2241*67e74705SXin Li OffsetVar = new llvm::GlobalVariable(TheModule, IntTy,
2242*67e74705SXin Li false, llvm::GlobalValue::ExternalLinkage,
2243*67e74705SXin Li OffsetValue,
2244*67e74705SXin Li "__objc_ivar_offset_value_" + ClassName +"." +
2245*67e74705SXin Li IVD->getNameAsString());
2246*67e74705SXin Li IvarOffsets.push_back(OffsetValue);
2247*67e74705SXin Li IvarOffsetValues.push_back(OffsetVar);
2248*67e74705SXin Li Qualifiers::ObjCLifetime lt = IVD->getType().getQualifiers().getObjCLifetime();
2249*67e74705SXin Li switch (lt) {
2250*67e74705SXin Li case Qualifiers::OCL_Strong:
2251*67e74705SXin Li StrongIvars.push_back(true);
2252*67e74705SXin Li WeakIvars.push_back(false);
2253*67e74705SXin Li break;
2254*67e74705SXin Li case Qualifiers::OCL_Weak:
2255*67e74705SXin Li StrongIvars.push_back(false);
2256*67e74705SXin Li WeakIvars.push_back(true);
2257*67e74705SXin Li break;
2258*67e74705SXin Li default:
2259*67e74705SXin Li StrongIvars.push_back(false);
2260*67e74705SXin Li WeakIvars.push_back(false);
2261*67e74705SXin Li }
2262*67e74705SXin Li }
2263*67e74705SXin Li llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
2264*67e74705SXin Li llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
2265*67e74705SXin Li llvm::GlobalVariable *IvarOffsetArray =
2266*67e74705SXin Li MakeGlobalArray(PtrToIntTy, IvarOffsetValues, CGM.getPointerAlign(),
2267*67e74705SXin Li ".ivar.offsets");
2268*67e74705SXin Li
2269*67e74705SXin Li // Collect information about instance methods
2270*67e74705SXin Li SmallVector<Selector, 16> InstanceMethodSels;
2271*67e74705SXin Li SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
2272*67e74705SXin Li for (const auto *I : OID->instance_methods()) {
2273*67e74705SXin Li InstanceMethodSels.push_back(I->getSelector());
2274*67e74705SXin Li std::string TypeStr;
2275*67e74705SXin Li Context.getObjCEncodingForMethodDecl(I,TypeStr);
2276*67e74705SXin Li InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2277*67e74705SXin Li }
2278*67e74705SXin Li
2279*67e74705SXin Li llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
2280*67e74705SXin Li InstanceMethodTypes);
2281*67e74705SXin Li
2282*67e74705SXin Li // Collect information about class methods
2283*67e74705SXin Li SmallVector<Selector, 16> ClassMethodSels;
2284*67e74705SXin Li SmallVector<llvm::Constant*, 16> ClassMethodTypes;
2285*67e74705SXin Li for (const auto *I : OID->class_methods()) {
2286*67e74705SXin Li ClassMethodSels.push_back(I->getSelector());
2287*67e74705SXin Li std::string TypeStr;
2288*67e74705SXin Li Context.getObjCEncodingForMethodDecl(I,TypeStr);
2289*67e74705SXin Li ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2290*67e74705SXin Li }
2291*67e74705SXin Li // Collect the names of referenced protocols
2292*67e74705SXin Li SmallVector<std::string, 16> Protocols;
2293*67e74705SXin Li for (const auto *I : ClassDecl->protocols())
2294*67e74705SXin Li Protocols.push_back(I->getNameAsString());
2295*67e74705SXin Li
2296*67e74705SXin Li // Get the superclass pointer.
2297*67e74705SXin Li llvm::Constant *SuperClass;
2298*67e74705SXin Li if (!SuperClassName.empty()) {
2299*67e74705SXin Li SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
2300*67e74705SXin Li } else {
2301*67e74705SXin Li SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2302*67e74705SXin Li }
2303*67e74705SXin Li // Empty vector used to construct empty method lists
2304*67e74705SXin Li SmallVector<llvm::Constant*, 1> empty;
2305*67e74705SXin Li // Generate the method and instance variable lists
2306*67e74705SXin Li llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
2307*67e74705SXin Li InstanceMethodSels, InstanceMethodTypes, false);
2308*67e74705SXin Li llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
2309*67e74705SXin Li ClassMethodSels, ClassMethodTypes, true);
2310*67e74705SXin Li llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
2311*67e74705SXin Li IvarOffsets);
2312*67e74705SXin Li // Irrespective of whether we are compiling for a fragile or non-fragile ABI,
2313*67e74705SXin Li // we emit a symbol containing the offset for each ivar in the class. This
2314*67e74705SXin Li // allows code compiled for the non-Fragile ABI to inherit from code compiled
2315*67e74705SXin Li // for the legacy ABI, without causing problems. The converse is also
2316*67e74705SXin Li // possible, but causes all ivar accesses to be fragile.
2317*67e74705SXin Li
2318*67e74705SXin Li // Offset pointer for getting at the correct field in the ivar list when
2319*67e74705SXin Li // setting up the alias. These are: The base address for the global, the
2320*67e74705SXin Li // ivar array (second field), the ivar in this list (set for each ivar), and
2321*67e74705SXin Li // the offset (third field in ivar structure)
2322*67e74705SXin Li llvm::Type *IndexTy = Int32Ty;
2323*67e74705SXin Li llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
2324*67e74705SXin Li llvm::ConstantInt::get(IndexTy, 1), nullptr,
2325*67e74705SXin Li llvm::ConstantInt::get(IndexTy, 2) };
2326*67e74705SXin Li
2327*67e74705SXin Li unsigned ivarIndex = 0;
2328*67e74705SXin Li for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD;
2329*67e74705SXin Li IVD = IVD->getNextIvar()) {
2330*67e74705SXin Li const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
2331*67e74705SXin Li + IVD->getNameAsString();
2332*67e74705SXin Li offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
2333*67e74705SXin Li // Get the correct ivar field
2334*67e74705SXin Li llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
2335*67e74705SXin Li cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
2336*67e74705SXin Li offsetPointerIndexes);
2337*67e74705SXin Li // Get the existing variable, if one exists.
2338*67e74705SXin Li llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
2339*67e74705SXin Li if (offset) {
2340*67e74705SXin Li offset->setInitializer(offsetValue);
2341*67e74705SXin Li // If this is the real definition, change its linkage type so that
2342*67e74705SXin Li // different modules will use this one, rather than their private
2343*67e74705SXin Li // copy.
2344*67e74705SXin Li offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
2345*67e74705SXin Li } else {
2346*67e74705SXin Li // Add a new alias if there isn't one already.
2347*67e74705SXin Li offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
2348*67e74705SXin Li false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
2349*67e74705SXin Li (void) offset; // Silence dead store warning.
2350*67e74705SXin Li }
2351*67e74705SXin Li ++ivarIndex;
2352*67e74705SXin Li }
2353*67e74705SXin Li llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
2354*67e74705SXin Li //Generate metaclass for class methods
2355*67e74705SXin Li llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
2356*67e74705SXin Li NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0], GenerateIvarList(
2357*67e74705SXin Li empty, empty, empty), ClassMethodList, NULLPtr,
2358*67e74705SXin Li NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true);
2359*67e74705SXin Li
2360*67e74705SXin Li // Generate the class structure
2361*67e74705SXin Li llvm::Constant *ClassStruct =
2362*67e74705SXin Li GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
2363*67e74705SXin Li ClassName.c_str(), nullptr,
2364*67e74705SXin Li llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
2365*67e74705SXin Li MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
2366*67e74705SXin Li Properties, StrongIvarBitmap, WeakIvarBitmap);
2367*67e74705SXin Li
2368*67e74705SXin Li // Resolve the class aliases, if they exist.
2369*67e74705SXin Li if (ClassPtrAlias) {
2370*67e74705SXin Li ClassPtrAlias->replaceAllUsesWith(
2371*67e74705SXin Li llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
2372*67e74705SXin Li ClassPtrAlias->eraseFromParent();
2373*67e74705SXin Li ClassPtrAlias = nullptr;
2374*67e74705SXin Li }
2375*67e74705SXin Li if (MetaClassPtrAlias) {
2376*67e74705SXin Li MetaClassPtrAlias->replaceAllUsesWith(
2377*67e74705SXin Li llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
2378*67e74705SXin Li MetaClassPtrAlias->eraseFromParent();
2379*67e74705SXin Li MetaClassPtrAlias = nullptr;
2380*67e74705SXin Li }
2381*67e74705SXin Li
2382*67e74705SXin Li // Add class structure to list to be added to the symtab later
2383*67e74705SXin Li ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
2384*67e74705SXin Li Classes.push_back(ClassStruct);
2385*67e74705SXin Li }
2386*67e74705SXin Li
ModuleInitFunction()2387*67e74705SXin Li llvm::Function *CGObjCGNU::ModuleInitFunction() {
2388*67e74705SXin Li // Only emit an ObjC load function if no Objective-C stuff has been called
2389*67e74705SXin Li if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
2390*67e74705SXin Li ExistingProtocols.empty() && SelectorTable.empty())
2391*67e74705SXin Li return nullptr;
2392*67e74705SXin Li
2393*67e74705SXin Li // Add all referenced protocols to a category.
2394*67e74705SXin Li GenerateProtocolHolderCategory();
2395*67e74705SXin Li
2396*67e74705SXin Li llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
2397*67e74705SXin Li SelectorTy->getElementType());
2398*67e74705SXin Li llvm::Type *SelStructPtrTy = SelectorTy;
2399*67e74705SXin Li if (!SelStructTy) {
2400*67e74705SXin Li SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, nullptr);
2401*67e74705SXin Li SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
2402*67e74705SXin Li }
2403*67e74705SXin Li
2404*67e74705SXin Li std::vector<llvm::Constant*> Elements;
2405*67e74705SXin Li llvm::Constant *Statics = NULLPtr;
2406*67e74705SXin Li // Generate statics list:
2407*67e74705SXin Li if (!ConstantStrings.empty()) {
2408*67e74705SXin Li llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
2409*67e74705SXin Li ConstantStrings.size() + 1);
2410*67e74705SXin Li ConstantStrings.push_back(NULLPtr);
2411*67e74705SXin Li
2412*67e74705SXin Li StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2413*67e74705SXin Li
2414*67e74705SXin Li if (StringClass.empty()) StringClass = "NXConstantString";
2415*67e74705SXin Li
2416*67e74705SXin Li Elements.push_back(MakeConstantString(StringClass,
2417*67e74705SXin Li ".objc_static_class_name"));
2418*67e74705SXin Li Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
2419*67e74705SXin Li ConstantStrings));
2420*67e74705SXin Li llvm::StructType *StaticsListTy =
2421*67e74705SXin Li llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, nullptr);
2422*67e74705SXin Li llvm::Type *StaticsListPtrTy =
2423*67e74705SXin Li llvm::PointerType::getUnqual(StaticsListTy);
2424*67e74705SXin Li Statics = MakeGlobal(StaticsListTy, Elements, CGM.getPointerAlign(),
2425*67e74705SXin Li ".objc_statics");
2426*67e74705SXin Li llvm::ArrayType *StaticsListArrayTy =
2427*67e74705SXin Li llvm::ArrayType::get(StaticsListPtrTy, 2);
2428*67e74705SXin Li Elements.clear();
2429*67e74705SXin Li Elements.push_back(Statics);
2430*67e74705SXin Li Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
2431*67e74705SXin Li Statics = MakeGlobal(StaticsListArrayTy, Elements,
2432*67e74705SXin Li CGM.getPointerAlign(), ".objc_statics_ptr");
2433*67e74705SXin Li Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
2434*67e74705SXin Li }
2435*67e74705SXin Li // Array of classes, categories, and constant objects
2436*67e74705SXin Li llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
2437*67e74705SXin Li Classes.size() + Categories.size() + 2);
2438*67e74705SXin Li llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy,
2439*67e74705SXin Li llvm::Type::getInt16Ty(VMContext),
2440*67e74705SXin Li llvm::Type::getInt16Ty(VMContext),
2441*67e74705SXin Li ClassListTy, nullptr);
2442*67e74705SXin Li
2443*67e74705SXin Li Elements.clear();
2444*67e74705SXin Li // Pointer to an array of selectors used in this module.
2445*67e74705SXin Li std::vector<llvm::Constant*> Selectors;
2446*67e74705SXin Li std::vector<llvm::GlobalAlias*> SelectorAliases;
2447*67e74705SXin Li for (SelectorMap::iterator iter = SelectorTable.begin(),
2448*67e74705SXin Li iterEnd = SelectorTable.end(); iter != iterEnd ; ++iter) {
2449*67e74705SXin Li
2450*67e74705SXin Li std::string SelNameStr = iter->first.getAsString();
2451*67e74705SXin Li llvm::Constant *SelName = ExportUniqueString(SelNameStr, ".objc_sel_name");
2452*67e74705SXin Li
2453*67e74705SXin Li SmallVectorImpl<TypedSelector> &Types = iter->second;
2454*67e74705SXin Li for (SmallVectorImpl<TypedSelector>::iterator i = Types.begin(),
2455*67e74705SXin Li e = Types.end() ; i!=e ; i++) {
2456*67e74705SXin Li
2457*67e74705SXin Li llvm::Constant *SelectorTypeEncoding = NULLPtr;
2458*67e74705SXin Li if (!i->first.empty())
2459*67e74705SXin Li SelectorTypeEncoding = MakeConstantString(i->first, ".objc_sel_types");
2460*67e74705SXin Li
2461*67e74705SXin Li Elements.push_back(SelName);
2462*67e74705SXin Li Elements.push_back(SelectorTypeEncoding);
2463*67e74705SXin Li Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2464*67e74705SXin Li Elements.clear();
2465*67e74705SXin Li
2466*67e74705SXin Li // Store the selector alias for later replacement
2467*67e74705SXin Li SelectorAliases.push_back(i->second);
2468*67e74705SXin Li }
2469*67e74705SXin Li }
2470*67e74705SXin Li unsigned SelectorCount = Selectors.size();
2471*67e74705SXin Li // NULL-terminate the selector list. This should not actually be required,
2472*67e74705SXin Li // because the selector list has a length field. Unfortunately, the GCC
2473*67e74705SXin Li // runtime decides to ignore the length field and expects a NULL terminator,
2474*67e74705SXin Li // and GCC cooperates with this by always setting the length to 0.
2475*67e74705SXin Li Elements.push_back(NULLPtr);
2476*67e74705SXin Li Elements.push_back(NULLPtr);
2477*67e74705SXin Li Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2478*67e74705SXin Li Elements.clear();
2479*67e74705SXin Li
2480*67e74705SXin Li // Number of static selectors
2481*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(LongTy, SelectorCount));
2482*67e74705SXin Li llvm::GlobalVariable *SelectorList =
2483*67e74705SXin Li MakeGlobalArray(SelStructTy, Selectors, CGM.getPointerAlign(),
2484*67e74705SXin Li ".objc_selector_list");
2485*67e74705SXin Li Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
2486*67e74705SXin Li SelStructPtrTy));
2487*67e74705SXin Li
2488*67e74705SXin Li // Now that all of the static selectors exist, create pointers to them.
2489*67e74705SXin Li for (unsigned int i=0 ; i<SelectorCount ; i++) {
2490*67e74705SXin Li
2491*67e74705SXin Li llvm::Constant *Idxs[] = {Zeros[0],
2492*67e74705SXin Li llvm::ConstantInt::get(Int32Ty, i), Zeros[0]};
2493*67e74705SXin Li // FIXME: We're generating redundant loads and stores here!
2494*67e74705SXin Li llvm::Constant *SelPtr = llvm::ConstantExpr::getGetElementPtr(
2495*67e74705SXin Li SelectorList->getValueType(), SelectorList, makeArrayRef(Idxs, 2));
2496*67e74705SXin Li // If selectors are defined as an opaque type, cast the pointer to this
2497*67e74705SXin Li // type.
2498*67e74705SXin Li SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, SelectorTy);
2499*67e74705SXin Li SelectorAliases[i]->replaceAllUsesWith(SelPtr);
2500*67e74705SXin Li SelectorAliases[i]->eraseFromParent();
2501*67e74705SXin Li }
2502*67e74705SXin Li
2503*67e74705SXin Li // Number of classes defined.
2504*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2505*67e74705SXin Li Classes.size()));
2506*67e74705SXin Li // Number of categories defined
2507*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2508*67e74705SXin Li Categories.size()));
2509*67e74705SXin Li // Create an array of classes, then categories, then static object instances
2510*67e74705SXin Li Classes.insert(Classes.end(), Categories.begin(), Categories.end());
2511*67e74705SXin Li // NULL-terminated list of static object instances (mainly constant strings)
2512*67e74705SXin Li Classes.push_back(Statics);
2513*67e74705SXin Li Classes.push_back(NULLPtr);
2514*67e74705SXin Li llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
2515*67e74705SXin Li Elements.push_back(ClassList);
2516*67e74705SXin Li // Construct the symbol table
2517*67e74705SXin Li llvm::Constant *SymTab =
2518*67e74705SXin Li MakeGlobal(SymTabTy, Elements, CGM.getPointerAlign());
2519*67e74705SXin Li
2520*67e74705SXin Li // The symbol table is contained in a module which has some version-checking
2521*67e74705SXin Li // constants
2522*67e74705SXin Li llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
2523*67e74705SXin Li PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy),
2524*67e74705SXin Li (RuntimeVersion >= 10) ? IntTy : nullptr, nullptr);
2525*67e74705SXin Li Elements.clear();
2526*67e74705SXin Li // Runtime version, used for ABI compatibility checking.
2527*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
2528*67e74705SXin Li // sizeof(ModuleTy)
2529*67e74705SXin Li llvm::DataLayout td(&TheModule);
2530*67e74705SXin Li Elements.push_back(
2531*67e74705SXin Li llvm::ConstantInt::get(LongTy,
2532*67e74705SXin Li td.getTypeSizeInBits(ModuleTy) /
2533*67e74705SXin Li CGM.getContext().getCharWidth()));
2534*67e74705SXin Li
2535*67e74705SXin Li // The path to the source file where this module was declared
2536*67e74705SXin Li SourceManager &SM = CGM.getContext().getSourceManager();
2537*67e74705SXin Li const FileEntry *mainFile = SM.getFileEntryForID(SM.getMainFileID());
2538*67e74705SXin Li std::string path =
2539*67e74705SXin Li std::string(mainFile->getDir()->getName()) + '/' + mainFile->getName();
2540*67e74705SXin Li Elements.push_back(MakeConstantString(path, ".objc_source_file_name"));
2541*67e74705SXin Li Elements.push_back(SymTab);
2542*67e74705SXin Li
2543*67e74705SXin Li if (RuntimeVersion >= 10)
2544*67e74705SXin Li switch (CGM.getLangOpts().getGC()) {
2545*67e74705SXin Li case LangOptions::GCOnly:
2546*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(IntTy, 2));
2547*67e74705SXin Li break;
2548*67e74705SXin Li case LangOptions::NonGC:
2549*67e74705SXin Li if (CGM.getLangOpts().ObjCAutoRefCount)
2550*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2551*67e74705SXin Li else
2552*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(IntTy, 0));
2553*67e74705SXin Li break;
2554*67e74705SXin Li case LangOptions::HybridGC:
2555*67e74705SXin Li Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2556*67e74705SXin Li break;
2557*67e74705SXin Li }
2558*67e74705SXin Li
2559*67e74705SXin Li llvm::Value *Module = MakeGlobal(ModuleTy, Elements, CGM.getPointerAlign());
2560*67e74705SXin Li
2561*67e74705SXin Li // Create the load function calling the runtime entry point with the module
2562*67e74705SXin Li // structure
2563*67e74705SXin Li llvm::Function * LoadFunction = llvm::Function::Create(
2564*67e74705SXin Li llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
2565*67e74705SXin Li llvm::GlobalValue::InternalLinkage, ".objc_load_function",
2566*67e74705SXin Li &TheModule);
2567*67e74705SXin Li llvm::BasicBlock *EntryBB =
2568*67e74705SXin Li llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
2569*67e74705SXin Li CGBuilderTy Builder(CGM, VMContext);
2570*67e74705SXin Li Builder.SetInsertPoint(EntryBB);
2571*67e74705SXin Li
2572*67e74705SXin Li llvm::FunctionType *FT =
2573*67e74705SXin Li llvm::FunctionType::get(Builder.getVoidTy(),
2574*67e74705SXin Li llvm::PointerType::getUnqual(ModuleTy), true);
2575*67e74705SXin Li llvm::Value *Register = CGM.CreateRuntimeFunction(FT, "__objc_exec_class");
2576*67e74705SXin Li Builder.CreateCall(Register, Module);
2577*67e74705SXin Li
2578*67e74705SXin Li if (!ClassAliases.empty()) {
2579*67e74705SXin Li llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
2580*67e74705SXin Li llvm::FunctionType *RegisterAliasTy =
2581*67e74705SXin Li llvm::FunctionType::get(Builder.getVoidTy(),
2582*67e74705SXin Li ArgTypes, false);
2583*67e74705SXin Li llvm::Function *RegisterAlias = llvm::Function::Create(
2584*67e74705SXin Li RegisterAliasTy,
2585*67e74705SXin Li llvm::GlobalValue::ExternalWeakLinkage, "class_registerAlias_np",
2586*67e74705SXin Li &TheModule);
2587*67e74705SXin Li llvm::BasicBlock *AliasBB =
2588*67e74705SXin Li llvm::BasicBlock::Create(VMContext, "alias", LoadFunction);
2589*67e74705SXin Li llvm::BasicBlock *NoAliasBB =
2590*67e74705SXin Li llvm::BasicBlock::Create(VMContext, "no_alias", LoadFunction);
2591*67e74705SXin Li
2592*67e74705SXin Li // Branch based on whether the runtime provided class_registerAlias_np()
2593*67e74705SXin Li llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
2594*67e74705SXin Li llvm::Constant::getNullValue(RegisterAlias->getType()));
2595*67e74705SXin Li Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
2596*67e74705SXin Li
2597*67e74705SXin Li // The true branch (has alias registration function):
2598*67e74705SXin Li Builder.SetInsertPoint(AliasBB);
2599*67e74705SXin Li // Emit alias registration calls:
2600*67e74705SXin Li for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
2601*67e74705SXin Li iter != ClassAliases.end(); ++iter) {
2602*67e74705SXin Li llvm::Constant *TheClass =
2603*67e74705SXin Li TheModule.getGlobalVariable(("_OBJC_CLASS_" + iter->first).c_str(),
2604*67e74705SXin Li true);
2605*67e74705SXin Li if (TheClass) {
2606*67e74705SXin Li TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
2607*67e74705SXin Li Builder.CreateCall(RegisterAlias,
2608*67e74705SXin Li {TheClass, MakeConstantString(iter->second)});
2609*67e74705SXin Li }
2610*67e74705SXin Li }
2611*67e74705SXin Li // Jump to end:
2612*67e74705SXin Li Builder.CreateBr(NoAliasBB);
2613*67e74705SXin Li
2614*67e74705SXin Li // Missing alias registration function, just return from the function:
2615*67e74705SXin Li Builder.SetInsertPoint(NoAliasBB);
2616*67e74705SXin Li }
2617*67e74705SXin Li Builder.CreateRetVoid();
2618*67e74705SXin Li
2619*67e74705SXin Li return LoadFunction;
2620*67e74705SXin Li }
2621*67e74705SXin Li
GenerateMethod(const ObjCMethodDecl * OMD,const ObjCContainerDecl * CD)2622*67e74705SXin Li llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
2623*67e74705SXin Li const ObjCContainerDecl *CD) {
2624*67e74705SXin Li const ObjCCategoryImplDecl *OCD =
2625*67e74705SXin Li dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext());
2626*67e74705SXin Li StringRef CategoryName = OCD ? OCD->getName() : "";
2627*67e74705SXin Li StringRef ClassName = CD->getName();
2628*67e74705SXin Li Selector MethodName = OMD->getSelector();
2629*67e74705SXin Li bool isClassMethod = !OMD->isInstanceMethod();
2630*67e74705SXin Li
2631*67e74705SXin Li CodeGenTypes &Types = CGM.getTypes();
2632*67e74705SXin Li llvm::FunctionType *MethodTy =
2633*67e74705SXin Li Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
2634*67e74705SXin Li std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
2635*67e74705SXin Li MethodName, isClassMethod);
2636*67e74705SXin Li
2637*67e74705SXin Li llvm::Function *Method
2638*67e74705SXin Li = llvm::Function::Create(MethodTy,
2639*67e74705SXin Li llvm::GlobalValue::InternalLinkage,
2640*67e74705SXin Li FunctionName,
2641*67e74705SXin Li &TheModule);
2642*67e74705SXin Li return Method;
2643*67e74705SXin Li }
2644*67e74705SXin Li
GetPropertyGetFunction()2645*67e74705SXin Li llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
2646*67e74705SXin Li return GetPropertyFn;
2647*67e74705SXin Li }
2648*67e74705SXin Li
GetPropertySetFunction()2649*67e74705SXin Li llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
2650*67e74705SXin Li return SetPropertyFn;
2651*67e74705SXin Li }
2652*67e74705SXin Li
GetOptimizedPropertySetFunction(bool atomic,bool copy)2653*67e74705SXin Li llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic,
2654*67e74705SXin Li bool copy) {
2655*67e74705SXin Li return nullptr;
2656*67e74705SXin Li }
2657*67e74705SXin Li
GetGetStructFunction()2658*67e74705SXin Li llvm::Constant *CGObjCGNU::GetGetStructFunction() {
2659*67e74705SXin Li return GetStructPropertyFn;
2660*67e74705SXin Li }
2661*67e74705SXin Li
GetSetStructFunction()2662*67e74705SXin Li llvm::Constant *CGObjCGNU::GetSetStructFunction() {
2663*67e74705SXin Li return SetStructPropertyFn;
2664*67e74705SXin Li }
2665*67e74705SXin Li
GetCppAtomicObjectGetFunction()2666*67e74705SXin Li llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
2667*67e74705SXin Li return nullptr;
2668*67e74705SXin Li }
2669*67e74705SXin Li
GetCppAtomicObjectSetFunction()2670*67e74705SXin Li llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
2671*67e74705SXin Li return nullptr;
2672*67e74705SXin Li }
2673*67e74705SXin Li
EnumerationMutationFunction()2674*67e74705SXin Li llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
2675*67e74705SXin Li return EnumerationMutationFn;
2676*67e74705SXin Li }
2677*67e74705SXin Li
EmitSynchronizedStmt(CodeGenFunction & CGF,const ObjCAtSynchronizedStmt & S)2678*67e74705SXin Li void CGObjCGNU::EmitSynchronizedStmt(CodeGenFunction &CGF,
2679*67e74705SXin Li const ObjCAtSynchronizedStmt &S) {
2680*67e74705SXin Li EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
2681*67e74705SXin Li }
2682*67e74705SXin Li
2683*67e74705SXin Li
EmitTryStmt(CodeGenFunction & CGF,const ObjCAtTryStmt & S)2684*67e74705SXin Li void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF,
2685*67e74705SXin Li const ObjCAtTryStmt &S) {
2686*67e74705SXin Li // Unlike the Apple non-fragile runtimes, which also uses
2687*67e74705SXin Li // unwind-based zero cost exceptions, the GNU Objective C runtime's
2688*67e74705SXin Li // EH support isn't a veneer over C++ EH. Instead, exception
2689*67e74705SXin Li // objects are created by objc_exception_throw and destroyed by
2690*67e74705SXin Li // the personality function; this avoids the need for bracketing
2691*67e74705SXin Li // catch handlers with calls to __blah_begin_catch/__blah_end_catch
2692*67e74705SXin Li // (or even _Unwind_DeleteException), but probably doesn't
2693*67e74705SXin Li // interoperate very well with foreign exceptions.
2694*67e74705SXin Li //
2695*67e74705SXin Li // In Objective-C++ mode, we actually emit something equivalent to the C++
2696*67e74705SXin Li // exception handler.
2697*67e74705SXin Li EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
2698*67e74705SXin Li }
2699*67e74705SXin Li
EmitThrowStmt(CodeGenFunction & CGF,const ObjCAtThrowStmt & S,bool ClearInsertionPoint)2700*67e74705SXin Li void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
2701*67e74705SXin Li const ObjCAtThrowStmt &S,
2702*67e74705SXin Li bool ClearInsertionPoint) {
2703*67e74705SXin Li llvm::Value *ExceptionAsObject;
2704*67e74705SXin Li
2705*67e74705SXin Li if (const Expr *ThrowExpr = S.getThrowExpr()) {
2706*67e74705SXin Li llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
2707*67e74705SXin Li ExceptionAsObject = Exception;
2708*67e74705SXin Li } else {
2709*67e74705SXin Li assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
2710*67e74705SXin Li "Unexpected rethrow outside @catch block.");
2711*67e74705SXin Li ExceptionAsObject = CGF.ObjCEHValueStack.back();
2712*67e74705SXin Li }
2713*67e74705SXin Li ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
2714*67e74705SXin Li llvm::CallSite Throw =
2715*67e74705SXin Li CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
2716*67e74705SXin Li Throw.setDoesNotReturn();
2717*67e74705SXin Li CGF.Builder.CreateUnreachable();
2718*67e74705SXin Li if (ClearInsertionPoint)
2719*67e74705SXin Li CGF.Builder.ClearInsertionPoint();
2720*67e74705SXin Li }
2721*67e74705SXin Li
EmitObjCWeakRead(CodeGenFunction & CGF,Address AddrWeakObj)2722*67e74705SXin Li llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF,
2723*67e74705SXin Li Address AddrWeakObj) {
2724*67e74705SXin Li CGBuilderTy &B = CGF.Builder;
2725*67e74705SXin Li AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
2726*67e74705SXin Li return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
2727*67e74705SXin Li AddrWeakObj.getPointer());
2728*67e74705SXin Li }
2729*67e74705SXin Li
EmitObjCWeakAssign(CodeGenFunction & CGF,llvm::Value * src,Address dst)2730*67e74705SXin Li void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF,
2731*67e74705SXin Li llvm::Value *src, Address dst) {
2732*67e74705SXin Li CGBuilderTy &B = CGF.Builder;
2733*67e74705SXin Li src = EnforceType(B, src, IdTy);
2734*67e74705SXin Li dst = EnforceType(B, dst, PtrToIdTy);
2735*67e74705SXin Li B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
2736*67e74705SXin Li {src, dst.getPointer()});
2737*67e74705SXin Li }
2738*67e74705SXin Li
EmitObjCGlobalAssign(CodeGenFunction & CGF,llvm::Value * src,Address dst,bool threadlocal)2739*67e74705SXin Li void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
2740*67e74705SXin Li llvm::Value *src, Address dst,
2741*67e74705SXin Li bool threadlocal) {
2742*67e74705SXin Li CGBuilderTy &B = CGF.Builder;
2743*67e74705SXin Li src = EnforceType(B, src, IdTy);
2744*67e74705SXin Li dst = EnforceType(B, dst, PtrToIdTy);
2745*67e74705SXin Li // FIXME. Add threadloca assign API
2746*67e74705SXin Li assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI");
2747*67e74705SXin Li B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
2748*67e74705SXin Li {src, dst.getPointer()});
2749*67e74705SXin Li }
2750*67e74705SXin Li
EmitObjCIvarAssign(CodeGenFunction & CGF,llvm::Value * src,Address dst,llvm::Value * ivarOffset)2751*67e74705SXin Li void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF,
2752*67e74705SXin Li llvm::Value *src, Address dst,
2753*67e74705SXin Li llvm::Value *ivarOffset) {
2754*67e74705SXin Li CGBuilderTy &B = CGF.Builder;
2755*67e74705SXin Li src = EnforceType(B, src, IdTy);
2756*67e74705SXin Li dst = EnforceType(B, dst, IdTy);
2757*67e74705SXin Li B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
2758*67e74705SXin Li {src, dst.getPointer(), ivarOffset});
2759*67e74705SXin Li }
2760*67e74705SXin Li
EmitObjCStrongCastAssign(CodeGenFunction & CGF,llvm::Value * src,Address dst)2761*67e74705SXin Li void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF,
2762*67e74705SXin Li llvm::Value *src, Address dst) {
2763*67e74705SXin Li CGBuilderTy &B = CGF.Builder;
2764*67e74705SXin Li src = EnforceType(B, src, IdTy);
2765*67e74705SXin Li dst = EnforceType(B, dst, PtrToIdTy);
2766*67e74705SXin Li B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
2767*67e74705SXin Li {src, dst.getPointer()});
2768*67e74705SXin Li }
2769*67e74705SXin Li
EmitGCMemmoveCollectable(CodeGenFunction & CGF,Address DestPtr,Address SrcPtr,llvm::Value * Size)2770*67e74705SXin Li void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF,
2771*67e74705SXin Li Address DestPtr,
2772*67e74705SXin Li Address SrcPtr,
2773*67e74705SXin Li llvm::Value *Size) {
2774*67e74705SXin Li CGBuilderTy &B = CGF.Builder;
2775*67e74705SXin Li DestPtr = EnforceType(B, DestPtr, PtrTy);
2776*67e74705SXin Li SrcPtr = EnforceType(B, SrcPtr, PtrTy);
2777*67e74705SXin Li
2778*67e74705SXin Li B.CreateCall(MemMoveFn.getType(), MemMoveFn,
2779*67e74705SXin Li {DestPtr.getPointer(), SrcPtr.getPointer(), Size});
2780*67e74705SXin Li }
2781*67e74705SXin Li
ObjCIvarOffsetVariable(const ObjCInterfaceDecl * ID,const ObjCIvarDecl * Ivar)2782*67e74705SXin Li llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2783*67e74705SXin Li const ObjCInterfaceDecl *ID,
2784*67e74705SXin Li const ObjCIvarDecl *Ivar) {
2785*67e74705SXin Li const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
2786*67e74705SXin Li + '.' + Ivar->getNameAsString();
2787*67e74705SXin Li // Emit the variable and initialize it with what we think the correct value
2788*67e74705SXin Li // is. This allows code compiled with non-fragile ivars to work correctly
2789*67e74705SXin Li // when linked against code which isn't (most of the time).
2790*67e74705SXin Li llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2791*67e74705SXin Li if (!IvarOffsetPointer) {
2792*67e74705SXin Li // This will cause a run-time crash if we accidentally use it. A value of
2793*67e74705SXin Li // 0 would seem more sensible, but will silently overwrite the isa pointer
2794*67e74705SXin Li // causing a great deal of confusion.
2795*67e74705SXin Li uint64_t Offset = -1;
2796*67e74705SXin Li // We can't call ComputeIvarBaseOffset() here if we have the
2797*67e74705SXin Li // implementation, because it will create an invalid ASTRecordLayout object
2798*67e74705SXin Li // that we are then stuck with forever, so we only initialize the ivar
2799*67e74705SXin Li // offset variable with a guess if we only have the interface. The
2800*67e74705SXin Li // initializer will be reset later anyway, when we are generating the class
2801*67e74705SXin Li // description.
2802*67e74705SXin Li if (!CGM.getContext().getObjCImplementation(
2803*67e74705SXin Li const_cast<ObjCInterfaceDecl *>(ID)))
2804*67e74705SXin Li Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2805*67e74705SXin Li
2806*67e74705SXin Li llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
2807*67e74705SXin Li /*isSigned*/true);
2808*67e74705SXin Li // Don't emit the guess in non-PIC code because the linker will not be able
2809*67e74705SXin Li // to replace it with the real version for a library. In non-PIC code you
2810*67e74705SXin Li // must compile with the fragile ABI if you want to use ivars from a
2811*67e74705SXin Li // GCC-compiled class.
2812*67e74705SXin Li if (CGM.getLangOpts().PICLevel) {
2813*67e74705SXin Li llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
2814*67e74705SXin Li Int32Ty, false,
2815*67e74705SXin Li llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
2816*67e74705SXin Li IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
2817*67e74705SXin Li IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage,
2818*67e74705SXin Li IvarOffsetGV, Name);
2819*67e74705SXin Li } else {
2820*67e74705SXin Li IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
2821*67e74705SXin Li llvm::Type::getInt32PtrTy(VMContext), false,
2822*67e74705SXin Li llvm::GlobalValue::ExternalLinkage, nullptr, Name);
2823*67e74705SXin Li }
2824*67e74705SXin Li }
2825*67e74705SXin Li return IvarOffsetPointer;
2826*67e74705SXin Li }
2827*67e74705SXin Li
EmitObjCValueForIvar(CodeGenFunction & CGF,QualType ObjectTy,llvm::Value * BaseValue,const ObjCIvarDecl * Ivar,unsigned CVRQualifiers)2828*67e74705SXin Li LValue CGObjCGNU::EmitObjCValueForIvar(CodeGenFunction &CGF,
2829*67e74705SXin Li QualType ObjectTy,
2830*67e74705SXin Li llvm::Value *BaseValue,
2831*67e74705SXin Li const ObjCIvarDecl *Ivar,
2832*67e74705SXin Li unsigned CVRQualifiers) {
2833*67e74705SXin Li const ObjCInterfaceDecl *ID =
2834*67e74705SXin Li ObjectTy->getAs<ObjCObjectType>()->getInterface();
2835*67e74705SXin Li return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2836*67e74705SXin Li EmitIvarOffset(CGF, ID, Ivar));
2837*67e74705SXin Li }
2838*67e74705SXin Li
FindIvarInterface(ASTContext & Context,const ObjCInterfaceDecl * OID,const ObjCIvarDecl * OIVD)2839*67e74705SXin Li static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
2840*67e74705SXin Li const ObjCInterfaceDecl *OID,
2841*67e74705SXin Li const ObjCIvarDecl *OIVD) {
2842*67e74705SXin Li for (const ObjCIvarDecl *next = OID->all_declared_ivar_begin(); next;
2843*67e74705SXin Li next = next->getNextIvar()) {
2844*67e74705SXin Li if (OIVD == next)
2845*67e74705SXin Li return OID;
2846*67e74705SXin Li }
2847*67e74705SXin Li
2848*67e74705SXin Li // Otherwise check in the super class.
2849*67e74705SXin Li if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
2850*67e74705SXin Li return FindIvarInterface(Context, Super, OIVD);
2851*67e74705SXin Li
2852*67e74705SXin Li return nullptr;
2853*67e74705SXin Li }
2854*67e74705SXin Li
EmitIvarOffset(CodeGenFunction & CGF,const ObjCInterfaceDecl * Interface,const ObjCIvarDecl * Ivar)2855*67e74705SXin Li llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF,
2856*67e74705SXin Li const ObjCInterfaceDecl *Interface,
2857*67e74705SXin Li const ObjCIvarDecl *Ivar) {
2858*67e74705SXin Li if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2859*67e74705SXin Li Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
2860*67e74705SXin Li if (RuntimeVersion < 10)
2861*67e74705SXin Li return CGF.Builder.CreateZExtOrBitCast(
2862*67e74705SXin Li CGF.Builder.CreateDefaultAlignedLoad(CGF.Builder.CreateAlignedLoad(
2863*67e74705SXin Li ObjCIvarOffsetVariable(Interface, Ivar),
2864*67e74705SXin Li CGF.getPointerAlign(), "ivar")),
2865*67e74705SXin Li PtrDiffTy);
2866*67e74705SXin Li std::string name = "__objc_ivar_offset_value_" +
2867*67e74705SXin Li Interface->getNameAsString() +"." + Ivar->getNameAsString();
2868*67e74705SXin Li CharUnits Align = CGM.getIntAlign();
2869*67e74705SXin Li llvm::Value *Offset = TheModule.getGlobalVariable(name);
2870*67e74705SXin Li if (!Offset) {
2871*67e74705SXin Li auto GV = new llvm::GlobalVariable(TheModule, IntTy,
2872*67e74705SXin Li false, llvm::GlobalValue::LinkOnceAnyLinkage,
2873*67e74705SXin Li llvm::Constant::getNullValue(IntTy), name);
2874*67e74705SXin Li GV->setAlignment(Align.getQuantity());
2875*67e74705SXin Li Offset = GV;
2876*67e74705SXin Li }
2877*67e74705SXin Li Offset = CGF.Builder.CreateAlignedLoad(Offset, Align);
2878*67e74705SXin Li if (Offset->getType() != PtrDiffTy)
2879*67e74705SXin Li Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
2880*67e74705SXin Li return Offset;
2881*67e74705SXin Li }
2882*67e74705SXin Li uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
2883*67e74705SXin Li return llvm::ConstantInt::get(PtrDiffTy, Offset, /*isSigned*/true);
2884*67e74705SXin Li }
2885*67e74705SXin Li
2886*67e74705SXin Li CGObjCRuntime *
CreateGNUObjCRuntime(CodeGenModule & CGM)2887*67e74705SXin Li clang::CodeGen::CreateGNUObjCRuntime(CodeGenModule &CGM) {
2888*67e74705SXin Li switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
2889*67e74705SXin Li case ObjCRuntime::GNUstep:
2890*67e74705SXin Li return new CGObjCGNUstep(CGM);
2891*67e74705SXin Li
2892*67e74705SXin Li case ObjCRuntime::GCC:
2893*67e74705SXin Li return new CGObjCGCC(CGM);
2894*67e74705SXin Li
2895*67e74705SXin Li case ObjCRuntime::ObjFW:
2896*67e74705SXin Li return new CGObjCObjFW(CGM);
2897*67e74705SXin Li
2898*67e74705SXin Li case ObjCRuntime::FragileMacOSX:
2899*67e74705SXin Li case ObjCRuntime::MacOSX:
2900*67e74705SXin Li case ObjCRuntime::iOS:
2901*67e74705SXin Li case ObjCRuntime::WatchOS:
2902*67e74705SXin Li llvm_unreachable("these runtimes are not GNU runtimes");
2903*67e74705SXin Li }
2904*67e74705SXin Li llvm_unreachable("bad runtime");
2905*67e74705SXin Li }
2906