xref: /aosp_15_r20/external/clang/lib/CodeGen/CGObjCGNU.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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