File: | llvm/include/llvm/IR/IRBuilder.h |
Warning: | line 2128, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This provides Objective-C code generation targeting the GNU runtime. The | |||
10 | // class in this file generates structures used by the GNU Objective-C runtime | |||
11 | // library. These structures are defined in objc/objc.h and objc/objc-api.h in | |||
12 | // the GNU runtime distribution. | |||
13 | // | |||
14 | //===----------------------------------------------------------------------===// | |||
15 | ||||
16 | #include "CGCXXABI.h" | |||
17 | #include "CGCleanup.h" | |||
18 | #include "CGObjCRuntime.h" | |||
19 | #include "CodeGenFunction.h" | |||
20 | #include "CodeGenModule.h" | |||
21 | #include "clang/AST/ASTContext.h" | |||
22 | #include "clang/AST/Attr.h" | |||
23 | #include "clang/AST/Decl.h" | |||
24 | #include "clang/AST/DeclObjC.h" | |||
25 | #include "clang/AST/RecordLayout.h" | |||
26 | #include "clang/AST/StmtObjC.h" | |||
27 | #include "clang/Basic/FileManager.h" | |||
28 | #include "clang/Basic/SourceManager.h" | |||
29 | #include "clang/CodeGen/ConstantInitBuilder.h" | |||
30 | #include "llvm/ADT/SmallVector.h" | |||
31 | #include "llvm/ADT/StringMap.h" | |||
32 | #include "llvm/IR/DataLayout.h" | |||
33 | #include "llvm/IR/Intrinsics.h" | |||
34 | #include "llvm/IR/LLVMContext.h" | |||
35 | #include "llvm/IR/Module.h" | |||
36 | #include "llvm/Support/Compiler.h" | |||
37 | #include "llvm/Support/ConvertUTF.h" | |||
38 | #include <cctype> | |||
39 | ||||
40 | using namespace clang; | |||
41 | using namespace CodeGen; | |||
42 | ||||
43 | namespace { | |||
44 | ||||
45 | std::string SymbolNameForMethod( StringRef ClassName, | |||
46 | StringRef CategoryName, const Selector MethodName, | |||
47 | bool isClassMethod) { | |||
48 | std::string MethodNameColonStripped = MethodName.getAsString(); | |||
49 | std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(), | |||
50 | ':', '_'); | |||
51 | return (Twine(isClassMethod ? "_c_" : "_i_") + ClassName + "_" + | |||
52 | CategoryName + "_" + MethodNameColonStripped).str(); | |||
53 | } | |||
54 | ||||
55 | /// Class that lazily initialises the runtime function. Avoids inserting the | |||
56 | /// types and the function declaration into a module if they're not used, and | |||
57 | /// avoids constructing the type more than once if it's used more than once. | |||
58 | class LazyRuntimeFunction { | |||
59 | CodeGenModule *CGM; | |||
60 | llvm::FunctionType *FTy; | |||
61 | const char *FunctionName; | |||
62 | llvm::FunctionCallee Function; | |||
63 | ||||
64 | public: | |||
65 | /// Constructor leaves this class uninitialized, because it is intended to | |||
66 | /// be used as a field in another class and not all of the types that are | |||
67 | /// used as arguments will necessarily be available at construction time. | |||
68 | LazyRuntimeFunction() | |||
69 | : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {} | |||
70 | ||||
71 | /// Initialises the lazy function with the name, return type, and the types | |||
72 | /// of the arguments. | |||
73 | template <typename... Tys> | |||
74 | void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy, | |||
75 | Tys *... Types) { | |||
76 | CGM = Mod; | |||
77 | FunctionName = name; | |||
78 | Function = nullptr; | |||
79 | if(sizeof...(Tys)) { | |||
80 | SmallVector<llvm::Type *, 8> ArgTys({Types...}); | |||
81 | FTy = llvm::FunctionType::get(RetTy, ArgTys, false); | |||
82 | } | |||
83 | else { | |||
84 | FTy = llvm::FunctionType::get(RetTy, None, false); | |||
85 | } | |||
86 | } | |||
87 | ||||
88 | llvm::FunctionType *getType() { return FTy; } | |||
89 | ||||
90 | /// Overloaded cast operator, allows the class to be implicitly cast to an | |||
91 | /// LLVM constant. | |||
92 | operator llvm::FunctionCallee() { | |||
93 | if (!Function) { | |||
94 | if (!FunctionName) | |||
95 | return nullptr; | |||
96 | Function = CGM->CreateRuntimeFunction(FTy, FunctionName); | |||
97 | } | |||
98 | return Function; | |||
99 | } | |||
100 | }; | |||
101 | ||||
102 | ||||
103 | /// GNU Objective-C runtime code generation. This class implements the parts of | |||
104 | /// Objective-C support that are specific to the GNU family of runtimes (GCC, | |||
105 | /// GNUstep and ObjFW). | |||
106 | class CGObjCGNU : public CGObjCRuntime { | |||
107 | protected: | |||
108 | /// The LLVM module into which output is inserted | |||
109 | llvm::Module &TheModule; | |||
110 | /// strut objc_super. Used for sending messages to super. This structure | |||
111 | /// contains the receiver (object) and the expected class. | |||
112 | llvm::StructType *ObjCSuperTy; | |||
113 | /// struct objc_super*. The type of the argument to the superclass message | |||
114 | /// lookup functions. | |||
115 | llvm::PointerType *PtrToObjCSuperTy; | |||
116 | /// LLVM type for selectors. Opaque pointer (i8*) unless a header declaring | |||
117 | /// SEL is included in a header somewhere, in which case it will be whatever | |||
118 | /// type is declared in that header, most likely {i8*, i8*}. | |||
119 | llvm::PointerType *SelectorTy; | |||
120 | /// LLVM i8 type. Cached here to avoid repeatedly getting it in all of the | |||
121 | /// places where it's used | |||
122 | llvm::IntegerType *Int8Ty; | |||
123 | /// Pointer to i8 - LLVM type of char*, for all of the places where the | |||
124 | /// runtime needs to deal with C strings. | |||
125 | llvm::PointerType *PtrToInt8Ty; | |||
126 | /// struct objc_protocol type | |||
127 | llvm::StructType *ProtocolTy; | |||
128 | /// Protocol * type. | |||
129 | llvm::PointerType *ProtocolPtrTy; | |||
130 | /// Instance Method Pointer type. This is a pointer to a function that takes, | |||
131 | /// at a minimum, an object and a selector, and is the generic type for | |||
132 | /// Objective-C methods. Due to differences between variadic / non-variadic | |||
133 | /// calling conventions, it must always be cast to the correct type before | |||
134 | /// actually being used. | |||
135 | llvm::PointerType *IMPTy; | |||
136 | /// Type of an untyped Objective-C object. Clang treats id as a built-in type | |||
137 | /// when compiling Objective-C code, so this may be an opaque pointer (i8*), | |||
138 | /// but if the runtime header declaring it is included then it may be a | |||
139 | /// pointer to a structure. | |||
140 | llvm::PointerType *IdTy; | |||
141 | /// Pointer to a pointer to an Objective-C object. Used in the new ABI | |||
142 | /// message lookup function and some GC-related functions. | |||
143 | llvm::PointerType *PtrToIdTy; | |||
144 | /// The clang type of id. Used when using the clang CGCall infrastructure to | |||
145 | /// call Objective-C methods. | |||
146 | CanQualType ASTIdTy; | |||
147 | /// LLVM type for C int type. | |||
148 | llvm::IntegerType *IntTy; | |||
149 | /// LLVM type for an opaque pointer. This is identical to PtrToInt8Ty, but is | |||
150 | /// used in the code to document the difference between i8* meaning a pointer | |||
151 | /// to a C string and i8* meaning a pointer to some opaque type. | |||
152 | llvm::PointerType *PtrTy; | |||
153 | /// LLVM type for C long type. The runtime uses this in a lot of places where | |||
154 | /// it should be using intptr_t, but we can't fix this without breaking | |||
155 | /// compatibility with GCC... | |||
156 | llvm::IntegerType *LongTy; | |||
157 | /// LLVM type for C size_t. Used in various runtime data structures. | |||
158 | llvm::IntegerType *SizeTy; | |||
159 | /// LLVM type for C intptr_t. | |||
160 | llvm::IntegerType *IntPtrTy; | |||
161 | /// LLVM type for C ptrdiff_t. Mainly used in property accessor functions. | |||
162 | llvm::IntegerType *PtrDiffTy; | |||
163 | /// LLVM type for C int*. Used for GCC-ABI-compatible non-fragile instance | |||
164 | /// variables. | |||
165 | llvm::PointerType *PtrToIntTy; | |||
166 | /// LLVM type for Objective-C BOOL type. | |||
167 | llvm::Type *BoolTy; | |||
168 | /// 32-bit integer type, to save us needing to look it up every time it's used. | |||
169 | llvm::IntegerType *Int32Ty; | |||
170 | /// 64-bit integer type, to save us needing to look it up every time it's used. | |||
171 | llvm::IntegerType *Int64Ty; | |||
172 | /// The type of struct objc_property. | |||
173 | llvm::StructType *PropertyMetadataTy; | |||
174 | /// Metadata kind used to tie method lookups to message sends. The GNUstep | |||
175 | /// runtime provides some LLVM passes that can use this to do things like | |||
176 | /// automatic IMP caching and speculative inlining. | |||
177 | unsigned msgSendMDKind; | |||
178 | /// Does the current target use SEH-based exceptions? False implies | |||
179 | /// Itanium-style DWARF unwinding. | |||
180 | bool usesSEHExceptions; | |||
181 | ||||
182 | /// Helper to check if we are targeting a specific runtime version or later. | |||
183 | bool isRuntime(ObjCRuntime::Kind kind, unsigned major, unsigned minor=0) { | |||
184 | const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime; | |||
185 | return (R.getKind() == kind) && | |||
186 | (R.getVersion() >= VersionTuple(major, minor)); | |||
187 | } | |||
188 | ||||
189 | std::string ManglePublicSymbol(StringRef Name) { | |||
190 | return (StringRef(CGM.getTriple().isOSBinFormatCOFF() ? "$_" : "._") + Name).str(); | |||
191 | } | |||
192 | ||||
193 | std::string SymbolForProtocol(Twine Name) { | |||
194 | return (ManglePublicSymbol("OBJC_PROTOCOL_") + Name).str(); | |||
195 | } | |||
196 | ||||
197 | std::string SymbolForProtocolRef(StringRef Name) { | |||
198 | return (ManglePublicSymbol("OBJC_REF_PROTOCOL_") + Name).str(); | |||
199 | } | |||
200 | ||||
201 | ||||
202 | /// Helper function that generates a constant string and returns a pointer to | |||
203 | /// the start of the string. The result of this function can be used anywhere | |||
204 | /// where the C code specifies const char*. | |||
205 | llvm::Constant *MakeConstantString(StringRef Str, const char *Name = "") { | |||
206 | ConstantAddress Array = CGM.GetAddrOfConstantCString(Str, Name); | |||
207 | return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(), | |||
208 | Array.getPointer(), Zeros); | |||
209 | } | |||
210 | ||||
211 | /// Emits a linkonce_odr string, whose name is the prefix followed by the | |||
212 | /// string value. This allows the linker to combine the strings between | |||
213 | /// different modules. Used for EH typeinfo names, selector strings, and a | |||
214 | /// few other things. | |||
215 | llvm::Constant *ExportUniqueString(const std::string &Str, | |||
216 | const std::string &prefix, | |||
217 | bool Private=false) { | |||
218 | std::string name = prefix + Str; | |||
219 | auto *ConstStr = TheModule.getGlobalVariable(name); | |||
220 | if (!ConstStr) { | |||
221 | llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str); | |||
222 | auto *GV = new llvm::GlobalVariable(TheModule, value->getType(), true, | |||
223 | llvm::GlobalValue::LinkOnceODRLinkage, value, name); | |||
224 | GV->setComdat(TheModule.getOrInsertComdat(name)); | |||
225 | if (Private) | |||
226 | GV->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
227 | ConstStr = GV; | |||
228 | } | |||
229 | return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(), | |||
230 | ConstStr, Zeros); | |||
231 | } | |||
232 | ||||
233 | /// Returns a property name and encoding string. | |||
234 | llvm::Constant *MakePropertyEncodingString(const ObjCPropertyDecl *PD, | |||
235 | const Decl *Container) { | |||
236 | assert(!isRuntime(ObjCRuntime::GNUstep, 2))((!isRuntime(ObjCRuntime::GNUstep, 2)) ? static_cast<void> (0) : __assert_fail ("!isRuntime(ObjCRuntime::GNUstep, 2)", "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 236, __PRETTY_FUNCTION__)); | |||
237 | if (isRuntime(ObjCRuntime::GNUstep, 1, 6)) { | |||
238 | std::string NameAndAttributes; | |||
239 | std::string TypeStr = | |||
240 | CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); | |||
241 | NameAndAttributes += '\0'; | |||
242 | NameAndAttributes += TypeStr.length() + 3; | |||
243 | NameAndAttributes += TypeStr; | |||
244 | NameAndAttributes += '\0'; | |||
245 | NameAndAttributes += PD->getNameAsString(); | |||
246 | return MakeConstantString(NameAndAttributes); | |||
247 | } | |||
248 | return MakeConstantString(PD->getNameAsString()); | |||
249 | } | |||
250 | ||||
251 | /// Push the property attributes into two structure fields. | |||
252 | void PushPropertyAttributes(ConstantStructBuilder &Fields, | |||
253 | const ObjCPropertyDecl *property, bool isSynthesized=true, bool | |||
254 | isDynamic=true) { | |||
255 | int attrs = property->getPropertyAttributes(); | |||
256 | // For read-only properties, clear the copy and retain flags | |||
257 | if (attrs & ObjCPropertyDecl::OBJC_PR_readonly) { | |||
258 | attrs &= ~ObjCPropertyDecl::OBJC_PR_copy; | |||
259 | attrs &= ~ObjCPropertyDecl::OBJC_PR_retain; | |||
260 | attrs &= ~ObjCPropertyDecl::OBJC_PR_weak; | |||
261 | attrs &= ~ObjCPropertyDecl::OBJC_PR_strong; | |||
262 | } | |||
263 | // The first flags field has the same attribute values as clang uses internally | |||
264 | Fields.addInt(Int8Ty, attrs & 0xff); | |||
265 | attrs >>= 8; | |||
266 | attrs <<= 2; | |||
267 | // For protocol properties, synthesized and dynamic have no meaning, so we | |||
268 | // reuse these flags to indicate that this is a protocol property (both set | |||
269 | // has no meaning, as a property can't be both synthesized and dynamic) | |||
270 | attrs |= isSynthesized ? (1<<0) : 0; | |||
271 | attrs |= isDynamic ? (1<<1) : 0; | |||
272 | // The second field is the next four fields left shifted by two, with the | |||
273 | // low bit set to indicate whether the field is synthesized or dynamic. | |||
274 | Fields.addInt(Int8Ty, attrs & 0xff); | |||
275 | // Two padding fields | |||
276 | Fields.addInt(Int8Ty, 0); | |||
277 | Fields.addInt(Int8Ty, 0); | |||
278 | } | |||
279 | ||||
280 | virtual llvm::Constant *GenerateCategoryProtocolList(const | |||
281 | ObjCCategoryDecl *OCD); | |||
282 | virtual ConstantArrayBuilder PushPropertyListHeader(ConstantStructBuilder &Fields, | |||
283 | int count) { | |||
284 | // int count; | |||
285 | Fields.addInt(IntTy, count); | |||
286 | // int size; (only in GNUstep v2 ABI. | |||
287 | if (isRuntime(ObjCRuntime::GNUstep, 2)) { | |||
288 | llvm::DataLayout td(&TheModule); | |||
289 | Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) / | |||
290 | CGM.getContext().getCharWidth()); | |||
291 | } | |||
292 | // struct objc_property_list *next; | |||
293 | Fields.add(NULLPtr); | |||
294 | // struct objc_property properties[] | |||
295 | return Fields.beginArray(PropertyMetadataTy); | |||
296 | } | |||
297 | virtual void PushProperty(ConstantArrayBuilder &PropertiesArray, | |||
298 | const ObjCPropertyDecl *property, | |||
299 | const Decl *OCD, | |||
300 | bool isSynthesized=true, bool | |||
301 | isDynamic=true) { | |||
302 | auto Fields = PropertiesArray.beginStruct(PropertyMetadataTy); | |||
303 | ASTContext &Context = CGM.getContext(); | |||
304 | Fields.add(MakePropertyEncodingString(property, OCD)); | |||
305 | PushPropertyAttributes(Fields, property, isSynthesized, isDynamic); | |||
306 | auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) { | |||
307 | if (accessor) { | |||
308 | std::string TypeStr = Context.getObjCEncodingForMethodDecl(accessor); | |||
309 | llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); | |||
310 | Fields.add(MakeConstantString(accessor->getSelector().getAsString())); | |||
311 | Fields.add(TypeEncoding); | |||
312 | } else { | |||
313 | Fields.add(NULLPtr); | |||
314 | Fields.add(NULLPtr); | |||
315 | } | |||
316 | }; | |||
317 | addPropertyMethod(property->getGetterMethodDecl()); | |||
318 | addPropertyMethod(property->getSetterMethodDecl()); | |||
319 | Fields.finishAndAddTo(PropertiesArray); | |||
320 | } | |||
321 | ||||
322 | /// Ensures that the value has the required type, by inserting a bitcast if | |||
323 | /// required. This function lets us avoid inserting bitcasts that are | |||
324 | /// redundant. | |||
325 | llvm::Value* EnforceType(CGBuilderTy &B, llvm::Value *V, llvm::Type *Ty) { | |||
326 | if (V->getType() == Ty) return V; | |||
327 | return B.CreateBitCast(V, Ty); | |||
328 | } | |||
329 | Address EnforceType(CGBuilderTy &B, Address V, llvm::Type *Ty) { | |||
330 | if (V.getType() == Ty) return V; | |||
331 | return B.CreateBitCast(V, Ty); | |||
332 | } | |||
333 | ||||
334 | // Some zeros used for GEPs in lots of places. | |||
335 | llvm::Constant *Zeros[2]; | |||
336 | /// Null pointer value. Mainly used as a terminator in various arrays. | |||
337 | llvm::Constant *NULLPtr; | |||
338 | /// LLVM context. | |||
339 | llvm::LLVMContext &VMContext; | |||
340 | ||||
341 | protected: | |||
342 | ||||
343 | /// Placeholder for the class. Lots of things refer to the class before we've | |||
344 | /// actually emitted it. We use this alias as a placeholder, and then replace | |||
345 | /// it with a pointer to the class structure before finally emitting the | |||
346 | /// module. | |||
347 | llvm::GlobalAlias *ClassPtrAlias; | |||
348 | /// Placeholder for the metaclass. Lots of things refer to the class before | |||
349 | /// we've / actually emitted it. We use this alias as a placeholder, and then | |||
350 | /// replace / it with a pointer to the metaclass structure before finally | |||
351 | /// emitting the / module. | |||
352 | llvm::GlobalAlias *MetaClassPtrAlias; | |||
353 | /// All of the classes that have been generated for this compilation units. | |||
354 | std::vector<llvm::Constant*> Classes; | |||
355 | /// All of the categories that have been generated for this compilation units. | |||
356 | std::vector<llvm::Constant*> Categories; | |||
357 | /// All of the Objective-C constant strings that have been generated for this | |||
358 | /// compilation units. | |||
359 | std::vector<llvm::Constant*> ConstantStrings; | |||
360 | /// Map from string values to Objective-C constant strings in the output. | |||
361 | /// Used to prevent emitting Objective-C strings more than once. This should | |||
362 | /// not be required at all - CodeGenModule should manage this list. | |||
363 | llvm::StringMap<llvm::Constant*> ObjCStrings; | |||
364 | /// All of the protocols that have been declared. | |||
365 | llvm::StringMap<llvm::Constant*> ExistingProtocols; | |||
366 | /// For each variant of a selector, we store the type encoding and a | |||
367 | /// placeholder value. For an untyped selector, the type will be the empty | |||
368 | /// string. Selector references are all done via the module's selector table, | |||
369 | /// so we create an alias as a placeholder and then replace it with the real | |||
370 | /// value later. | |||
371 | typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector; | |||
372 | /// Type of the selector map. This is roughly equivalent to the structure | |||
373 | /// used in the GNUstep runtime, which maintains a list of all of the valid | |||
374 | /// types for a selector in a table. | |||
375 | typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> > | |||
376 | SelectorMap; | |||
377 | /// A map from selectors to selector types. This allows us to emit all | |||
378 | /// selectors of the same name and type together. | |||
379 | SelectorMap SelectorTable; | |||
380 | ||||
381 | /// Selectors related to memory management. When compiling in GC mode, we | |||
382 | /// omit these. | |||
383 | Selector RetainSel, ReleaseSel, AutoreleaseSel; | |||
384 | /// Runtime functions used for memory management in GC mode. Note that clang | |||
385 | /// supports code generation for calling these functions, but neither GNU | |||
386 | /// runtime actually supports this API properly yet. | |||
387 | LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn, | |||
388 | WeakAssignFn, GlobalAssignFn; | |||
389 | ||||
390 | typedef std::pair<std::string, std::string> ClassAliasPair; | |||
391 | /// All classes that have aliases set for them. | |||
392 | std::vector<ClassAliasPair> ClassAliases; | |||
393 | ||||
394 | protected: | |||
395 | /// Function used for throwing Objective-C exceptions. | |||
396 | LazyRuntimeFunction ExceptionThrowFn; | |||
397 | /// Function used for rethrowing exceptions, used at the end of \@finally or | |||
398 | /// \@synchronize blocks. | |||
399 | LazyRuntimeFunction ExceptionReThrowFn; | |||
400 | /// Function called when entering a catch function. This is required for | |||
401 | /// differentiating Objective-C exceptions and foreign exceptions. | |||
402 | LazyRuntimeFunction EnterCatchFn; | |||
403 | /// Function called when exiting from a catch block. Used to do exception | |||
404 | /// cleanup. | |||
405 | LazyRuntimeFunction ExitCatchFn; | |||
406 | /// Function called when entering an \@synchronize block. Acquires the lock. | |||
407 | LazyRuntimeFunction SyncEnterFn; | |||
408 | /// Function called when exiting an \@synchronize block. Releases the lock. | |||
409 | LazyRuntimeFunction SyncExitFn; | |||
410 | ||||
411 | private: | |||
412 | /// Function called if fast enumeration detects that the collection is | |||
413 | /// modified during the update. | |||
414 | LazyRuntimeFunction EnumerationMutationFn; | |||
415 | /// Function for implementing synthesized property getters that return an | |||
416 | /// object. | |||
417 | LazyRuntimeFunction GetPropertyFn; | |||
418 | /// Function for implementing synthesized property setters that return an | |||
419 | /// object. | |||
420 | LazyRuntimeFunction SetPropertyFn; | |||
421 | /// Function used for non-object declared property getters. | |||
422 | LazyRuntimeFunction GetStructPropertyFn; | |||
423 | /// Function used for non-object declared property setters. | |||
424 | LazyRuntimeFunction SetStructPropertyFn; | |||
425 | ||||
426 | protected: | |||
427 | /// The version of the runtime that this class targets. Must match the | |||
428 | /// version in the runtime. | |||
429 | int RuntimeVersion; | |||
430 | /// The version of the protocol class. Used to differentiate between ObjC1 | |||
431 | /// and ObjC2 protocols. Objective-C 1 protocols can not contain optional | |||
432 | /// components and can not contain declared properties. We always emit | |||
433 | /// Objective-C 2 property structures, but we have to pretend that they're | |||
434 | /// Objective-C 1 property structures when targeting the GCC runtime or it | |||
435 | /// will abort. | |||
436 | const int ProtocolVersion; | |||
437 | /// The version of the class ABI. This value is used in the class structure | |||
438 | /// and indicates how various fields should be interpreted. | |||
439 | const int ClassABIVersion; | |||
440 | /// Generates an instance variable list structure. This is a structure | |||
441 | /// containing a size and an array of structures containing instance variable | |||
442 | /// metadata. This is used purely for introspection in the fragile ABI. In | |||
443 | /// the non-fragile ABI, it's used for instance variable fixup. | |||
444 | virtual llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames, | |||
445 | ArrayRef<llvm::Constant *> IvarTypes, | |||
446 | ArrayRef<llvm::Constant *> IvarOffsets, | |||
447 | ArrayRef<llvm::Constant *> IvarAlign, | |||
448 | ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership); | |||
449 | ||||
450 | /// Generates a method list structure. This is a structure containing a size | |||
451 | /// and an array of structures containing method metadata. | |||
452 | /// | |||
453 | /// This structure is used by both classes and categories, and contains a next | |||
454 | /// pointer allowing them to be chained together in a linked list. | |||
455 | llvm::Constant *GenerateMethodList(StringRef ClassName, | |||
456 | StringRef CategoryName, | |||
457 | ArrayRef<const ObjCMethodDecl*> Methods, | |||
458 | bool isClassMethodList); | |||
459 | ||||
460 | /// Emits an empty protocol. This is used for \@protocol() where no protocol | |||
461 | /// is found. The runtime will (hopefully) fix up the pointer to refer to the | |||
462 | /// real protocol. | |||
463 | virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName); | |||
464 | ||||
465 | /// Generates a list of property metadata structures. This follows the same | |||
466 | /// pattern as method and instance variable metadata lists. | |||
467 | llvm::Constant *GeneratePropertyList(const Decl *Container, | |||
468 | const ObjCContainerDecl *OCD, | |||
469 | bool isClassProperty=false, | |||
470 | bool protocolOptionalProperties=false); | |||
471 | ||||
472 | /// Generates a list of referenced protocols. Classes, categories, and | |||
473 | /// protocols all use this structure. | |||
474 | llvm::Constant *GenerateProtocolList(ArrayRef<std::string> Protocols); | |||
475 | ||||
476 | /// To ensure that all protocols are seen by the runtime, we add a category on | |||
477 | /// a class defined in the runtime, declaring no methods, but adopting the | |||
478 | /// protocols. This is a horribly ugly hack, but it allows us to collect all | |||
479 | /// of the protocols without changing the ABI. | |||
480 | void GenerateProtocolHolderCategory(); | |||
481 | ||||
482 | /// Generates a class structure. | |||
483 | llvm::Constant *GenerateClassStructure( | |||
484 | llvm::Constant *MetaClass, | |||
485 | llvm::Constant *SuperClass, | |||
486 | unsigned info, | |||
487 | const char *Name, | |||
488 | llvm::Constant *Version, | |||
489 | llvm::Constant *InstanceSize, | |||
490 | llvm::Constant *IVars, | |||
491 | llvm::Constant *Methods, | |||
492 | llvm::Constant *Protocols, | |||
493 | llvm::Constant *IvarOffsets, | |||
494 | llvm::Constant *Properties, | |||
495 | llvm::Constant *StrongIvarBitmap, | |||
496 | llvm::Constant *WeakIvarBitmap, | |||
497 | bool isMeta=false); | |||
498 | ||||
499 | /// Generates a method list. This is used by protocols to define the required | |||
500 | /// and optional methods. | |||
501 | virtual llvm::Constant *GenerateProtocolMethodList( | |||
502 | ArrayRef<const ObjCMethodDecl*> Methods); | |||
503 | /// Emits optional and required method lists. | |||
504 | template<class T> | |||
505 | void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required, | |||
506 | llvm::Constant *&Optional) { | |||
507 | SmallVector<const ObjCMethodDecl*, 16> RequiredMethods; | |||
508 | SmallVector<const ObjCMethodDecl*, 16> OptionalMethods; | |||
509 | for (const auto *I : Methods) | |||
510 | if (I->isOptional()) | |||
511 | OptionalMethods.push_back(I); | |||
512 | else | |||
513 | RequiredMethods.push_back(I); | |||
514 | Required = GenerateProtocolMethodList(RequiredMethods); | |||
515 | Optional = GenerateProtocolMethodList(OptionalMethods); | |||
516 | } | |||
517 | ||||
518 | /// Returns a selector with the specified type encoding. An empty string is | |||
519 | /// used to return an untyped selector (with the types field set to NULL). | |||
520 | virtual llvm::Value *GetTypedSelector(CodeGenFunction &CGF, Selector Sel, | |||
521 | const std::string &TypeEncoding); | |||
522 | ||||
523 | /// Returns the name of ivar offset variables. In the GNUstep v1 ABI, this | |||
524 | /// contains the class and ivar names, in the v2 ABI this contains the type | |||
525 | /// encoding as well. | |||
526 | virtual std::string GetIVarOffsetVariableName(const ObjCInterfaceDecl *ID, | |||
527 | const ObjCIvarDecl *Ivar) { | |||
528 | const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() | |||
529 | + '.' + Ivar->getNameAsString(); | |||
530 | return Name; | |||
531 | } | |||
532 | /// Returns the variable used to store the offset of an instance variable. | |||
533 | llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, | |||
534 | const ObjCIvarDecl *Ivar); | |||
535 | /// Emits a reference to a class. This allows the linker to object if there | |||
536 | /// is no class of the matching name. | |||
537 | void EmitClassRef(const std::string &className); | |||
538 | ||||
539 | /// Emits a pointer to the named class | |||
540 | virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF, | |||
541 | const std::string &Name, bool isWeak); | |||
542 | ||||
543 | /// Looks up the method for sending a message to the specified object. This | |||
544 | /// mechanism differs between the GCC and GNU runtimes, so this method must be | |||
545 | /// overridden in subclasses. | |||
546 | virtual llvm::Value *LookupIMP(CodeGenFunction &CGF, | |||
547 | llvm::Value *&Receiver, | |||
548 | llvm::Value *cmd, | |||
549 | llvm::MDNode *node, | |||
550 | MessageSendInfo &MSI) = 0; | |||
551 | ||||
552 | /// Looks up the method for sending a message to a superclass. This | |||
553 | /// mechanism differs between the GCC and GNU runtimes, so this method must | |||
554 | /// be overridden in subclasses. | |||
555 | virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, | |||
556 | Address ObjCSuper, | |||
557 | llvm::Value *cmd, | |||
558 | MessageSendInfo &MSI) = 0; | |||
559 | ||||
560 | /// Libobjc2 uses a bitfield representation where small(ish) bitfields are | |||
561 | /// stored in a 64-bit value with the low bit set to 1 and the remaining 63 | |||
562 | /// bits set to their values, LSB first, while larger ones are stored in a | |||
563 | /// structure of this / form: | |||
564 | /// | |||
565 | /// struct { int32_t length; int32_t values[length]; }; | |||
566 | /// | |||
567 | /// The values in the array are stored in host-endian format, with the least | |||
568 | /// significant bit being assumed to come first in the bitfield. Therefore, | |||
569 | /// a bitfield with the 64th bit set will be (int64_t)&{ 2, [0, 1<<31] }, | |||
570 | /// while a bitfield / with the 63rd bit set will be 1<<64. | |||
571 | llvm::Constant *MakeBitField(ArrayRef<bool> bits); | |||
572 | ||||
573 | public: | |||
574 | CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion, | |||
575 | unsigned protocolClassVersion, unsigned classABI=1); | |||
576 | ||||
577 | ConstantAddress GenerateConstantString(const StringLiteral *) override; | |||
578 | ||||
579 | RValue | |||
580 | GenerateMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return, | |||
581 | QualType ResultType, Selector Sel, | |||
582 | llvm::Value *Receiver, const CallArgList &CallArgs, | |||
583 | const ObjCInterfaceDecl *Class, | |||
584 | const ObjCMethodDecl *Method) override; | |||
585 | RValue | |||
586 | GenerateMessageSendSuper(CodeGenFunction &CGF, ReturnValueSlot Return, | |||
587 | QualType ResultType, Selector Sel, | |||
588 | const ObjCInterfaceDecl *Class, | |||
589 | bool isCategoryImpl, llvm::Value *Receiver, | |||
590 | bool IsClassMessage, const CallArgList &CallArgs, | |||
591 | const ObjCMethodDecl *Method) override; | |||
592 | llvm::Value *GetClass(CodeGenFunction &CGF, | |||
593 | const ObjCInterfaceDecl *OID) override; | |||
594 | llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override; | |||
595 | Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override; | |||
596 | llvm::Value *GetSelector(CodeGenFunction &CGF, | |||
597 | const ObjCMethodDecl *Method) override; | |||
598 | virtual llvm::Constant *GetConstantSelector(Selector Sel, | |||
599 | const std::string &TypeEncoding) { | |||
600 | llvm_unreachable("Runtime unable to generate constant selector")::llvm::llvm_unreachable_internal("Runtime unable to generate constant selector" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 600); | |||
601 | } | |||
602 | llvm::Constant *GetConstantSelector(const ObjCMethodDecl *M) { | |||
603 | return GetConstantSelector(M->getSelector(), | |||
604 | CGM.getContext().getObjCEncodingForMethodDecl(M)); | |||
605 | } | |||
606 | llvm::Constant *GetEHType(QualType T) override; | |||
607 | ||||
608 | llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, | |||
609 | const ObjCContainerDecl *CD) override; | |||
610 | void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, | |||
611 | const ObjCMethodDecl *OMD, | |||
612 | const ObjCContainerDecl *CD) override; | |||
613 | void GenerateCategory(const ObjCCategoryImplDecl *CMD) override; | |||
614 | void GenerateClass(const ObjCImplementationDecl *ClassDecl) override; | |||
615 | void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override; | |||
616 | llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, | |||
617 | const ObjCProtocolDecl *PD) override; | |||
618 | void GenerateProtocol(const ObjCProtocolDecl *PD) override; | |||
619 | llvm::Function *ModuleInitFunction() override; | |||
620 | llvm::FunctionCallee GetPropertyGetFunction() override; | |||
621 | llvm::FunctionCallee GetPropertySetFunction() override; | |||
622 | llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, | |||
623 | bool copy) override; | |||
624 | llvm::FunctionCallee GetSetStructFunction() override; | |||
625 | llvm::FunctionCallee GetGetStructFunction() override; | |||
626 | llvm::FunctionCallee GetCppAtomicObjectGetFunction() override; | |||
627 | llvm::FunctionCallee GetCppAtomicObjectSetFunction() override; | |||
628 | llvm::FunctionCallee EnumerationMutationFunction() override; | |||
629 | ||||
630 | void EmitTryStmt(CodeGenFunction &CGF, | |||
631 | const ObjCAtTryStmt &S) override; | |||
632 | void EmitSynchronizedStmt(CodeGenFunction &CGF, | |||
633 | const ObjCAtSynchronizedStmt &S) override; | |||
634 | void EmitThrowStmt(CodeGenFunction &CGF, | |||
635 | const ObjCAtThrowStmt &S, | |||
636 | bool ClearInsertionPoint=true) override; | |||
637 | llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF, | |||
638 | Address AddrWeakObj) override; | |||
639 | void EmitObjCWeakAssign(CodeGenFunction &CGF, | |||
640 | llvm::Value *src, Address dst) override; | |||
641 | void EmitObjCGlobalAssign(CodeGenFunction &CGF, | |||
642 | llvm::Value *src, Address dest, | |||
643 | bool threadlocal=false) override; | |||
644 | void EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *src, | |||
645 | Address dest, llvm::Value *ivarOffset) override; | |||
646 | void EmitObjCStrongCastAssign(CodeGenFunction &CGF, | |||
647 | llvm::Value *src, Address dest) override; | |||
648 | void EmitGCMemmoveCollectable(CodeGenFunction &CGF, Address DestPtr, | |||
649 | Address SrcPtr, | |||
650 | llvm::Value *Size) override; | |||
651 | LValue EmitObjCValueForIvar(CodeGenFunction &CGF, QualType ObjectTy, | |||
652 | llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, | |||
653 | unsigned CVRQualifiers) override; | |||
654 | llvm::Value *EmitIvarOffset(CodeGenFunction &CGF, | |||
655 | const ObjCInterfaceDecl *Interface, | |||
656 | const ObjCIvarDecl *Ivar) override; | |||
657 | llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override; | |||
658 | llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM, | |||
659 | const CGBlockInfo &blockInfo) override { | |||
660 | return NULLPtr; | |||
661 | } | |||
662 | llvm::Constant *BuildRCBlockLayout(CodeGenModule &CGM, | |||
663 | const CGBlockInfo &blockInfo) override { | |||
664 | return NULLPtr; | |||
665 | } | |||
666 | ||||
667 | llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, QualType T) override { | |||
668 | return NULLPtr; | |||
669 | } | |||
670 | }; | |||
671 | ||||
672 | /// Class representing the legacy GCC Objective-C ABI. This is the default when | |||
673 | /// -fobjc-nonfragile-abi is not specified. | |||
674 | /// | |||
675 | /// The GCC ABI target actually generates code that is approximately compatible | |||
676 | /// with the new GNUstep runtime ABI, but refrains from using any features that | |||
677 | /// would not work with the GCC runtime. For example, clang always generates | |||
678 | /// the extended form of the class structure, and the extra fields are simply | |||
679 | /// ignored by GCC libobjc. | |||
680 | class CGObjCGCC : public CGObjCGNU { | |||
681 | /// The GCC ABI message lookup function. Returns an IMP pointing to the | |||
682 | /// method implementation for this message. | |||
683 | LazyRuntimeFunction MsgLookupFn; | |||
684 | /// The GCC ABI superclass message lookup function. Takes a pointer to a | |||
685 | /// structure describing the receiver and the class, and a selector as | |||
686 | /// arguments. Returns the IMP for the corresponding method. | |||
687 | LazyRuntimeFunction MsgLookupSuperFn; | |||
688 | ||||
689 | protected: | |||
690 | llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, | |||
691 | llvm::Value *cmd, llvm::MDNode *node, | |||
692 | MessageSendInfo &MSI) override { | |||
693 | CGBuilderTy &Builder = CGF.Builder; | |||
694 | llvm::Value *args[] = { | |||
695 | EnforceType(Builder, Receiver, IdTy), | |||
696 | EnforceType(Builder, cmd, SelectorTy) }; | |||
697 | llvm::CallBase *imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); | |||
698 | imp->setMetadata(msgSendMDKind, node); | |||
699 | return imp; | |||
700 | } | |||
701 | ||||
702 | llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, | |||
703 | llvm::Value *cmd, MessageSendInfo &MSI) override { | |||
704 | CGBuilderTy &Builder = CGF.Builder; | |||
705 | llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper, | |||
706 | PtrToObjCSuperTy).getPointer(), cmd}; | |||
707 | return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); | |||
708 | } | |||
709 | ||||
710 | public: | |||
711 | CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) { | |||
712 | // IMP objc_msg_lookup(id, SEL); | |||
713 | MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy); | |||
714 | // IMP objc_msg_lookup_super(struct objc_super*, SEL); | |||
715 | MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, | |||
716 | PtrToObjCSuperTy, SelectorTy); | |||
717 | } | |||
718 | }; | |||
719 | ||||
720 | /// Class used when targeting the new GNUstep runtime ABI. | |||
721 | class CGObjCGNUstep : public CGObjCGNU { | |||
722 | /// The slot lookup function. Returns a pointer to a cacheable structure | |||
723 | /// that contains (among other things) the IMP. | |||
724 | LazyRuntimeFunction SlotLookupFn; | |||
725 | /// The GNUstep ABI superclass message lookup function. Takes a pointer to | |||
726 | /// a structure describing the receiver and the class, and a selector as | |||
727 | /// arguments. Returns the slot for the corresponding method. Superclass | |||
728 | /// message lookup rarely changes, so this is a good caching opportunity. | |||
729 | LazyRuntimeFunction SlotLookupSuperFn; | |||
730 | /// Specialised function for setting atomic retain properties | |||
731 | LazyRuntimeFunction SetPropertyAtomic; | |||
732 | /// Specialised function for setting atomic copy properties | |||
733 | LazyRuntimeFunction SetPropertyAtomicCopy; | |||
734 | /// Specialised function for setting nonatomic retain properties | |||
735 | LazyRuntimeFunction SetPropertyNonAtomic; | |||
736 | /// Specialised function for setting nonatomic copy properties | |||
737 | LazyRuntimeFunction SetPropertyNonAtomicCopy; | |||
738 | /// Function to perform atomic copies of C++ objects with nontrivial copy | |||
739 | /// constructors from Objective-C ivars. | |||
740 | LazyRuntimeFunction CxxAtomicObjectGetFn; | |||
741 | /// Function to perform atomic copies of C++ objects with nontrivial copy | |||
742 | /// constructors to Objective-C ivars. | |||
743 | LazyRuntimeFunction CxxAtomicObjectSetFn; | |||
744 | /// Type of an slot structure pointer. This is returned by the various | |||
745 | /// lookup functions. | |||
746 | llvm::Type *SlotTy; | |||
747 | ||||
748 | public: | |||
749 | llvm::Constant *GetEHType(QualType T) override; | |||
750 | ||||
751 | protected: | |||
752 | llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, | |||
753 | llvm::Value *cmd, llvm::MDNode *node, | |||
754 | MessageSendInfo &MSI) override { | |||
755 | CGBuilderTy &Builder = CGF.Builder; | |||
756 | llvm::FunctionCallee LookupFn = SlotLookupFn; | |||
757 | ||||
758 | // Store the receiver on the stack so that we can reload it later | |||
759 | Address ReceiverPtr = | |||
760 | CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign()); | |||
761 | Builder.CreateStore(Receiver, ReceiverPtr); | |||
762 | ||||
763 | llvm::Value *self; | |||
764 | ||||
765 | if (isa<ObjCMethodDecl>(CGF.CurCodeDecl)) { | |||
766 | self = CGF.LoadObjCSelf(); | |||
767 | } else { | |||
768 | self = llvm::ConstantPointerNull::get(IdTy); | |||
769 | } | |||
770 | ||||
771 | // The lookup function is guaranteed not to capture the receiver pointer. | |||
772 | if (auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee())) | |||
773 | LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture); | |||
774 | ||||
775 | llvm::Value *args[] = { | |||
776 | EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), | |||
777 | EnforceType(Builder, cmd, SelectorTy), | |||
778 | EnforceType(Builder, self, IdTy) }; | |||
779 | llvm::CallBase *slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); | |||
780 | slot->setOnlyReadsMemory(); | |||
781 | slot->setMetadata(msgSendMDKind, node); | |||
782 | ||||
783 | // Load the imp from the slot | |||
784 | llvm::Value *imp = Builder.CreateAlignedLoad( | |||
785 | Builder.CreateStructGEP(nullptr, slot, 4), CGF.getPointerAlign()); | |||
786 | ||||
787 | // The lookup function may have changed the receiver, so make sure we use | |||
788 | // the new one. | |||
789 | Receiver = Builder.CreateLoad(ReceiverPtr, true); | |||
790 | return imp; | |||
791 | } | |||
792 | ||||
793 | llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, | |||
794 | llvm::Value *cmd, | |||
795 | MessageSendInfo &MSI) override { | |||
796 | CGBuilderTy &Builder = CGF.Builder; | |||
797 | llvm::Value *lookupArgs[] = {ObjCSuper.getPointer(), cmd}; | |||
798 | ||||
799 | llvm::CallInst *slot = | |||
800 | CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs); | |||
801 | slot->setOnlyReadsMemory(); | |||
802 | ||||
803 | return Builder.CreateAlignedLoad(Builder.CreateStructGEP(nullptr, slot, 4), | |||
804 | CGF.getPointerAlign()); | |||
805 | } | |||
806 | ||||
807 | public: | |||
808 | CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {} | |||
809 | CGObjCGNUstep(CodeGenModule &Mod, unsigned ABI, unsigned ProtocolABI, | |||
810 | unsigned ClassABI) : | |||
811 | CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) { | |||
812 | const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime; | |||
813 | ||||
814 | llvm::StructType *SlotStructTy = | |||
815 | llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy); | |||
816 | SlotTy = llvm::PointerType::getUnqual(SlotStructTy); | |||
817 | // Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender); | |||
818 | SlotLookupFn.init(&CGM, "objc_msg_lookup_sender", SlotTy, PtrToIdTy, | |||
819 | SelectorTy, IdTy); | |||
820 | // Slot_t objc_slot_lookup_super(struct objc_super*, SEL); | |||
821 | SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy, | |||
822 | PtrToObjCSuperTy, SelectorTy); | |||
823 | // If we're in ObjC++ mode, then we want to make | |||
824 | if (usesSEHExceptions) { | |||
825 | llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); | |||
826 | // void objc_exception_rethrow(void) | |||
827 | ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy); | |||
828 | } else if (CGM.getLangOpts().CPlusPlus) { | |||
829 | llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); | |||
830 | // void *__cxa_begin_catch(void *e) | |||
831 | EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy); | |||
832 | // void __cxa_end_catch(void) | |||
833 | ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy); | |||
834 | // void _Unwind_Resume_or_Rethrow(void*) | |||
835 | ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy, | |||
836 | PtrTy); | |||
837 | } else if (R.getVersion() >= VersionTuple(1, 7)) { | |||
838 | llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); | |||
839 | // id objc_begin_catch(void *e) | |||
840 | EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy); | |||
841 | // void objc_end_catch(void) | |||
842 | ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy); | |||
843 | // void _Unwind_Resume_or_Rethrow(void*) | |||
844 | ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy, PtrTy); | |||
845 | } | |||
846 | llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); | |||
847 | SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy, | |||
848 | SelectorTy, IdTy, PtrDiffTy); | |||
849 | SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy, | |||
850 | IdTy, SelectorTy, IdTy, PtrDiffTy); | |||
851 | SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy, | |||
852 | IdTy, SelectorTy, IdTy, PtrDiffTy); | |||
853 | SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy", | |||
854 | VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy); | |||
855 | // void objc_setCppObjectAtomic(void *dest, const void *src, void | |||
856 | // *helper); | |||
857 | CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy, | |||
858 | PtrTy, PtrTy); | |||
859 | // void objc_getCppObjectAtomic(void *dest, const void *src, void | |||
860 | // *helper); | |||
861 | CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy, | |||
862 | PtrTy, PtrTy); | |||
863 | } | |||
864 | ||||
865 | llvm::FunctionCallee GetCppAtomicObjectGetFunction() override { | |||
866 | // The optimised functions were added in version 1.7 of the GNUstep | |||
867 | // runtime. | |||
868 | assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=((CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple (1, 7)) ? static_cast<void> (0) : __assert_fail ("CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple(1, 7)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 869, __PRETTY_FUNCTION__)) | |||
869 | VersionTuple(1, 7))((CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple (1, 7)) ? static_cast<void> (0) : __assert_fail ("CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple(1, 7)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 869, __PRETTY_FUNCTION__)); | |||
870 | return CxxAtomicObjectGetFn; | |||
871 | } | |||
872 | ||||
873 | llvm::FunctionCallee GetCppAtomicObjectSetFunction() override { | |||
874 | // The optimised functions were added in version 1.7 of the GNUstep | |||
875 | // runtime. | |||
876 | assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=((CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple (1, 7)) ? static_cast<void> (0) : __assert_fail ("CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple(1, 7)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 877, __PRETTY_FUNCTION__)) | |||
877 | VersionTuple(1, 7))((CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple (1, 7)) ? static_cast<void> (0) : __assert_fail ("CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple(1, 7)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 877, __PRETTY_FUNCTION__)); | |||
878 | return CxxAtomicObjectSetFn; | |||
879 | } | |||
880 | ||||
881 | llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, | |||
882 | bool copy) override { | |||
883 | // The optimised property functions omit the GC check, and so are not | |||
884 | // safe to use in GC mode. The standard functions are fast in GC mode, | |||
885 | // so there is less advantage in using them. | |||
886 | assert ((CGM.getLangOpts().getGC() == LangOptions::NonGC))(((CGM.getLangOpts().getGC() == LangOptions::NonGC)) ? static_cast <void> (0) : __assert_fail ("(CGM.getLangOpts().getGC() == LangOptions::NonGC)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 886, __PRETTY_FUNCTION__)); | |||
887 | // The optimised functions were added in version 1.7 of the GNUstep | |||
888 | // runtime. | |||
889 | assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=((CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple (1, 7)) ? static_cast<void> (0) : __assert_fail ("CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple(1, 7)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 890, __PRETTY_FUNCTION__)) | |||
890 | VersionTuple(1, 7))((CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple (1, 7)) ? static_cast<void> (0) : __assert_fail ("CGM.getLangOpts().ObjCRuntime.getVersion() >= VersionTuple(1, 7)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 890, __PRETTY_FUNCTION__)); | |||
891 | ||||
892 | if (atomic) { | |||
893 | if (copy) return SetPropertyAtomicCopy; | |||
894 | return SetPropertyAtomic; | |||
895 | } | |||
896 | ||||
897 | return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic; | |||
898 | } | |||
899 | }; | |||
900 | ||||
901 | /// GNUstep Objective-C ABI version 2 implementation. | |||
902 | /// This is the ABI that provides a clean break with the legacy GCC ABI and | |||
903 | /// cleans up a number of things that were added to work around 1980s linkers. | |||
904 | class CGObjCGNUstep2 : public CGObjCGNUstep { | |||
905 | enum SectionKind | |||
906 | { | |||
907 | SelectorSection = 0, | |||
908 | ClassSection, | |||
909 | ClassReferenceSection, | |||
910 | CategorySection, | |||
911 | ProtocolSection, | |||
912 | ProtocolReferenceSection, | |||
913 | ClassAliasSection, | |||
914 | ConstantStringSection | |||
915 | }; | |||
916 | static const char *const SectionsBaseNames[8]; | |||
917 | static const char *const PECOFFSectionsBaseNames[8]; | |||
918 | template<SectionKind K> | |||
919 | std::string sectionName() { | |||
920 | if (CGM.getTriple().isOSBinFormatCOFF()) { | |||
921 | std::string name(PECOFFSectionsBaseNames[K]); | |||
922 | name += "$m"; | |||
923 | return name; | |||
924 | } | |||
925 | return SectionsBaseNames[K]; | |||
926 | } | |||
927 | /// The GCC ABI superclass message lookup function. Takes a pointer to a | |||
928 | /// structure describing the receiver and the class, and a selector as | |||
929 | /// arguments. Returns the IMP for the corresponding method. | |||
930 | LazyRuntimeFunction MsgLookupSuperFn; | |||
931 | /// A flag indicating if we've emitted at least one protocol. | |||
932 | /// If we haven't, then we need to emit an empty protocol, to ensure that the | |||
933 | /// __start__objc_protocols and __stop__objc_protocols sections exist. | |||
934 | bool EmittedProtocol = false; | |||
935 | /// A flag indicating if we've emitted at least one protocol reference. | |||
936 | /// If we haven't, then we need to emit an empty protocol, to ensure that the | |||
937 | /// __start__objc_protocol_refs and __stop__objc_protocol_refs sections | |||
938 | /// exist. | |||
939 | bool EmittedProtocolRef = false; | |||
940 | /// A flag indicating if we've emitted at least one class. | |||
941 | /// If we haven't, then we need to emit an empty protocol, to ensure that the | |||
942 | /// __start__objc_classes and __stop__objc_classes sections / exist. | |||
943 | bool EmittedClass = false; | |||
944 | /// Generate the name of a symbol for a reference to a class. Accesses to | |||
945 | /// classes should be indirected via this. | |||
946 | ||||
947 | typedef std::pair<std::string, std::pair<llvm::Constant*, int>> EarlyInitPair; | |||
948 | std::vector<EarlyInitPair> EarlyInitList; | |||
949 | ||||
950 | std::string SymbolForClassRef(StringRef Name, bool isWeak) { | |||
951 | if (isWeak) | |||
952 | return (ManglePublicSymbol("OBJC_WEAK_REF_CLASS_") + Name).str(); | |||
953 | else | |||
954 | return (ManglePublicSymbol("OBJC_REF_CLASS_") + Name).str(); | |||
955 | } | |||
956 | /// Generate the name of a class symbol. | |||
957 | std::string SymbolForClass(StringRef Name) { | |||
958 | return (ManglePublicSymbol("OBJC_CLASS_") + Name).str(); | |||
959 | } | |||
960 | void CallRuntimeFunction(CGBuilderTy &B, StringRef FunctionName, | |||
961 | ArrayRef<llvm::Value*> Args) { | |||
962 | SmallVector<llvm::Type *,8> Types; | |||
963 | for (auto *Arg : Args) | |||
964 | Types.push_back(Arg->getType()); | |||
965 | llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types, | |||
966 | false); | |||
967 | llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FT, FunctionName); | |||
968 | B.CreateCall(Fn, Args); | |||
969 | } | |||
970 | ||||
971 | ConstantAddress GenerateConstantString(const StringLiteral *SL) override { | |||
972 | ||||
973 | auto Str = SL->getString(); | |||
974 | CharUnits Align = CGM.getPointerAlign(); | |||
975 | ||||
976 | // Look for an existing one | |||
977 | llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str); | |||
978 | if (old != ObjCStrings.end()) | |||
979 | return ConstantAddress(old->getValue(), Align); | |||
980 | ||||
981 | bool isNonASCII = SL->containsNonAscii(); | |||
982 | ||||
983 | auto LiteralLength = SL->getLength(); | |||
984 | ||||
985 | if ((CGM.getTarget().getPointerWidth(0) == 64) && | |||
986 | (LiteralLength < 9) && !isNonASCII) { | |||
987 | // Tiny strings are only used on 64-bit platforms. They store 8 7-bit | |||
988 | // ASCII characters in the high 56 bits, followed by a 4-bit length and a | |||
989 | // 3-bit tag (which is always 4). | |||
990 | uint64_t str = 0; | |||
991 | // Fill in the characters | |||
992 | for (unsigned i=0 ; i<LiteralLength ; i++) | |||
993 | str |= ((uint64_t)SL->getCodeUnit(i)) << ((64 - 4 - 3) - (i*7)); | |||
994 | // Fill in the length | |||
995 | str |= LiteralLength << 3; | |||
996 | // Set the tag | |||
997 | str |= 4; | |||
998 | auto *ObjCStr = llvm::ConstantExpr::getIntToPtr( | |||
999 | llvm::ConstantInt::get(Int64Ty, str), IdTy); | |||
1000 | ObjCStrings[Str] = ObjCStr; | |||
1001 | return ConstantAddress(ObjCStr, Align); | |||
1002 | } | |||
1003 | ||||
1004 | StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass; | |||
1005 | ||||
1006 | if (StringClass.empty()) StringClass = "NSConstantString"; | |||
1007 | ||||
1008 | std::string Sym = SymbolForClass(StringClass); | |||
1009 | ||||
1010 | llvm::Constant *isa = TheModule.getNamedGlobal(Sym); | |||
1011 | ||||
1012 | if (!isa) { | |||
1013 | isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false, | |||
1014 | llvm::GlobalValue::ExternalLinkage, nullptr, Sym); | |||
1015 | if (CGM.getTriple().isOSBinFormatCOFF()) { | |||
1016 | cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); | |||
1017 | } | |||
1018 | } else if (isa->getType() != PtrToIdTy) | |||
1019 | isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy); | |||
1020 | ||||
1021 | // struct | |||
1022 | // { | |||
1023 | // Class isa; | |||
1024 | // uint32_t flags; | |||
1025 | // uint32_t length; // Number of codepoints | |||
1026 | // uint32_t size; // Number of bytes | |||
1027 | // uint32_t hash; | |||
1028 | // const char *data; | |||
1029 | // }; | |||
1030 | ||||
1031 | ConstantInitBuilder Builder(CGM); | |||
1032 | auto Fields = Builder.beginStruct(); | |||
1033 | if (!CGM.getTriple().isOSBinFormatCOFF()) { | |||
1034 | Fields.add(isa); | |||
1035 | } else { | |||
1036 | Fields.addNullPointer(PtrTy); | |||
1037 | } | |||
1038 | // For now, all non-ASCII strings are represented as UTF-16. As such, the | |||
1039 | // number of bytes is simply double the number of UTF-16 codepoints. In | |||
1040 | // ASCII strings, the number of bytes is equal to the number of non-ASCII | |||
1041 | // codepoints. | |||
1042 | if (isNonASCII) { | |||
1043 | unsigned NumU8CodeUnits = Str.size(); | |||
1044 | // A UTF-16 representation of a unicode string contains at most the same | |||
1045 | // number of code units as a UTF-8 representation. Allocate that much | |||
1046 | // space, plus one for the final null character. | |||
1047 | SmallVector<llvm::UTF16, 128> ToBuf(NumU8CodeUnits + 1); | |||
1048 | const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)Str.data(); | |||
1049 | llvm::UTF16 *ToPtr = &ToBuf[0]; | |||
1050 | (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits, | |||
1051 | &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion); | |||
1052 | uint32_t StringLength = ToPtr - &ToBuf[0]; | |||
1053 | // Add null terminator | |||
1054 | *ToPtr = 0; | |||
1055 | // Flags: 2 indicates UTF-16 encoding | |||
1056 | Fields.addInt(Int32Ty, 2); | |||
1057 | // Number of UTF-16 codepoints | |||
1058 | Fields.addInt(Int32Ty, StringLength); | |||
1059 | // Number of bytes | |||
1060 | Fields.addInt(Int32Ty, StringLength * 2); | |||
1061 | // Hash. Not currently initialised by the compiler. | |||
1062 | Fields.addInt(Int32Ty, 0); | |||
1063 | // pointer to the data string. | |||
1064 | auto Arr = llvm::makeArrayRef(&ToBuf[0], ToPtr+1); | |||
1065 | auto *C = llvm::ConstantDataArray::get(VMContext, Arr); | |||
1066 | auto *Buffer = new llvm::GlobalVariable(TheModule, C->getType(), | |||
1067 | /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, C, ".str"); | |||
1068 | Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); | |||
1069 | Fields.add(Buffer); | |||
1070 | } else { | |||
1071 | // Flags: 0 indicates ASCII encoding | |||
1072 | Fields.addInt(Int32Ty, 0); | |||
1073 | // Number of UTF-16 codepoints, each ASCII byte is a UTF-16 codepoint | |||
1074 | Fields.addInt(Int32Ty, Str.size()); | |||
1075 | // Number of bytes | |||
1076 | Fields.addInt(Int32Ty, Str.size()); | |||
1077 | // Hash. Not currently initialised by the compiler. | |||
1078 | Fields.addInt(Int32Ty, 0); | |||
1079 | // Data pointer | |||
1080 | Fields.add(MakeConstantString(Str)); | |||
1081 | } | |||
1082 | std::string StringName; | |||
1083 | bool isNamed = !isNonASCII; | |||
1084 | if (isNamed) { | |||
1085 | StringName = ".objc_str_"; | |||
1086 | for (int i=0,e=Str.size() ; i<e ; ++i) { | |||
1087 | unsigned char c = Str[i]; | |||
1088 | if (isalnum(c)) | |||
1089 | StringName += c; | |||
1090 | else if (c == ' ') | |||
1091 | StringName += '_'; | |||
1092 | else { | |||
1093 | isNamed = false; | |||
1094 | break; | |||
1095 | } | |||
1096 | } | |||
1097 | } | |||
1098 | auto *ObjCStrGV = | |||
1099 | Fields.finishAndCreateGlobal( | |||
1100 | isNamed ? StringRef(StringName) : ".objc_string", | |||
1101 | Align, false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage | |||
1102 | : llvm::GlobalValue::PrivateLinkage); | |||
1103 | ObjCStrGV->setSection(sectionName<ConstantStringSection>()); | |||
1104 | if (isNamed) { | |||
1105 | ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName)); | |||
1106 | ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1107 | } | |||
1108 | if (CGM.getTriple().isOSBinFormatCOFF()) { | |||
1109 | std::pair<llvm::Constant*, int> v{ObjCStrGV, 0}; | |||
1110 | EarlyInitList.emplace_back(Sym, v); | |||
1111 | } | |||
1112 | llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy); | |||
1113 | ObjCStrings[Str] = ObjCStr; | |||
1114 | ConstantStrings.push_back(ObjCStr); | |||
1115 | return ConstantAddress(ObjCStr, Align); | |||
1116 | } | |||
1117 | ||||
1118 | void PushProperty(ConstantArrayBuilder &PropertiesArray, | |||
1119 | const ObjCPropertyDecl *property, | |||
1120 | const Decl *OCD, | |||
1121 | bool isSynthesized=true, bool | |||
1122 | isDynamic=true) override { | |||
1123 | // struct objc_property | |||
1124 | // { | |||
1125 | // const char *name; | |||
1126 | // const char *attributes; | |||
1127 | // const char *type; | |||
1128 | // SEL getter; | |||
1129 | // SEL setter; | |||
1130 | // }; | |||
1131 | auto Fields = PropertiesArray.beginStruct(PropertyMetadataTy); | |||
1132 | ASTContext &Context = CGM.getContext(); | |||
1133 | Fields.add(MakeConstantString(property->getNameAsString())); | |||
1134 | std::string TypeStr = | |||
1135 | CGM.getContext().getObjCEncodingForPropertyDecl(property, OCD); | |||
1136 | Fields.add(MakeConstantString(TypeStr)); | |||
1137 | std::string typeStr; | |||
1138 | Context.getObjCEncodingForType(property->getType(), typeStr); | |||
1139 | Fields.add(MakeConstantString(typeStr)); | |||
1140 | auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) { | |||
1141 | if (accessor) { | |||
1142 | std::string TypeStr = Context.getObjCEncodingForMethodDecl(accessor); | |||
1143 | Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr)); | |||
1144 | } else { | |||
1145 | Fields.add(NULLPtr); | |||
1146 | } | |||
1147 | }; | |||
1148 | addPropertyMethod(property->getGetterMethodDecl()); | |||
1149 | addPropertyMethod(property->getSetterMethodDecl()); | |||
1150 | Fields.finishAndAddTo(PropertiesArray); | |||
1151 | } | |||
1152 | ||||
1153 | llvm::Constant * | |||
1154 | GenerateProtocolMethodList(ArrayRef<const ObjCMethodDecl*> Methods) override { | |||
1155 | // struct objc_protocol_method_description | |||
1156 | // { | |||
1157 | // SEL selector; | |||
1158 | // const char *types; | |||
1159 | // }; | |||
1160 | llvm::StructType *ObjCMethodDescTy = | |||
1161 | llvm::StructType::get(CGM.getLLVMContext(), | |||
1162 | { PtrToInt8Ty, PtrToInt8Ty }); | |||
1163 | ASTContext &Context = CGM.getContext(); | |||
1164 | ConstantInitBuilder Builder(CGM); | |||
1165 | // struct objc_protocol_method_description_list | |||
1166 | // { | |||
1167 | // int count; | |||
1168 | // int size; | |||
1169 | // struct objc_protocol_method_description methods[]; | |||
1170 | // }; | |||
1171 | auto MethodList = Builder.beginStruct(); | |||
1172 | // int count; | |||
1173 | MethodList.addInt(IntTy, Methods.size()); | |||
1174 | // int size; // sizeof(struct objc_method_description) | |||
1175 | llvm::DataLayout td(&TheModule); | |||
1176 | MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) / | |||
1177 | CGM.getContext().getCharWidth()); | |||
1178 | // struct objc_method_description[] | |||
1179 | auto MethodArray = MethodList.beginArray(ObjCMethodDescTy); | |||
1180 | for (auto *M : Methods) { | |||
1181 | auto Method = MethodArray.beginStruct(ObjCMethodDescTy); | |||
1182 | Method.add(CGObjCGNU::GetConstantSelector(M)); | |||
1183 | Method.add(GetTypeString(Context.getObjCEncodingForMethodDecl(M, true))); | |||
1184 | Method.finishAndAddTo(MethodArray); | |||
1185 | } | |||
1186 | MethodArray.finishAndAddTo(MethodList); | |||
1187 | return MethodList.finishAndCreateGlobal(".objc_protocol_method_list", | |||
1188 | CGM.getPointerAlign()); | |||
1189 | } | |||
1190 | llvm::Constant *GenerateCategoryProtocolList(const ObjCCategoryDecl *OCD) | |||
1191 | override { | |||
1192 | SmallVector<llvm::Constant*, 16> Protocols; | |||
1193 | for (const auto *PI : OCD->getReferencedProtocols()) | |||
1194 | Protocols.push_back( | |||
1195 | llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI), | |||
1196 | ProtocolPtrTy)); | |||
1197 | return GenerateProtocolList(Protocols); | |||
1198 | } | |||
1199 | ||||
1200 | llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, | |||
1201 | llvm::Value *cmd, MessageSendInfo &MSI) override { | |||
1202 | // Don't access the slot unless we're trying to cache the result. | |||
1203 | CGBuilderTy &Builder = CGF.Builder; | |||
1204 | llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, ObjCSuper, | |||
1205 | PtrToObjCSuperTy).getPointer(), cmd}; | |||
1206 | return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); | |||
1207 | } | |||
1208 | ||||
1209 | llvm::GlobalVariable *GetClassVar(StringRef Name, bool isWeak=false) { | |||
1210 | std::string SymbolName = SymbolForClassRef(Name, isWeak); | |||
1211 | auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName); | |||
1212 | if (ClassSymbol) | |||
1213 | return ClassSymbol; | |||
1214 | ClassSymbol = new llvm::GlobalVariable(TheModule, | |||
1215 | IdTy, false, llvm::GlobalValue::ExternalLinkage, | |||
1216 | nullptr, SymbolName); | |||
1217 | // If this is a weak symbol, then we are creating a valid definition for | |||
1218 | // the symbol, pointing to a weak definition of the real class pointer. If | |||
1219 | // this is not a weak reference, then we are expecting another compilation | |||
1220 | // unit to provide the real indirection symbol. | |||
1221 | if (isWeak) | |||
1222 | ClassSymbol->setInitializer(new llvm::GlobalVariable(TheModule, | |||
1223 | Int8Ty, false, llvm::GlobalValue::ExternalWeakLinkage, | |||
1224 | nullptr, SymbolForClass(Name))); | |||
1225 | else { | |||
1226 | if (CGM.getTriple().isOSBinFormatCOFF()) { | |||
1227 | IdentifierInfo &II = CGM.getContext().Idents.get(Name); | |||
1228 | TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); | |||
1229 | DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); | |||
1230 | ||||
1231 | const ObjCInterfaceDecl *OID = nullptr; | |||
1232 | for (const auto &Result : DC->lookup(&II)) | |||
1233 | if ((OID = dyn_cast<ObjCInterfaceDecl>(Result))) | |||
1234 | break; | |||
1235 | ||||
1236 | // The first Interface we find may be a @class, | |||
1237 | // which should only be treated as the source of | |||
1238 | // truth in the absence of a true declaration. | |||
1239 | const ObjCInterfaceDecl *OIDDef = OID->getDefinition(); | |||
1240 | if (OIDDef != nullptr) | |||
1241 | OID = OIDDef; | |||
1242 | ||||
1243 | auto Storage = llvm::GlobalValue::DefaultStorageClass; | |||
1244 | if (OID->hasAttr<DLLImportAttr>()) | |||
1245 | Storage = llvm::GlobalValue::DLLImportStorageClass; | |||
1246 | else if (OID->hasAttr<DLLExportAttr>()) | |||
1247 | Storage = llvm::GlobalValue::DLLExportStorageClass; | |||
1248 | ||||
1249 | cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage); | |||
1250 | } | |||
1251 | } | |||
1252 | assert(ClassSymbol->getName() == SymbolName)((ClassSymbol->getName() == SymbolName) ? static_cast<void > (0) : __assert_fail ("ClassSymbol->getName() == SymbolName" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1252, __PRETTY_FUNCTION__)); | |||
1253 | return ClassSymbol; | |||
1254 | } | |||
1255 | llvm::Value *GetClassNamed(CodeGenFunction &CGF, | |||
1256 | const std::string &Name, | |||
1257 | bool isWeak) override { | |||
1258 | return CGF.Builder.CreateLoad(Address(GetClassVar(Name, isWeak), | |||
1259 | CGM.getPointerAlign())); | |||
1260 | } | |||
1261 | int32_t FlagsForOwnership(Qualifiers::ObjCLifetime Ownership) { | |||
1262 | // typedef enum { | |||
1263 | // ownership_invalid = 0, | |||
1264 | // ownership_strong = 1, | |||
1265 | // ownership_weak = 2, | |||
1266 | // ownership_unsafe = 3 | |||
1267 | // } ivar_ownership; | |||
1268 | int Flag; | |||
1269 | switch (Ownership) { | |||
1270 | case Qualifiers::OCL_Strong: | |||
1271 | Flag = 1; | |||
1272 | break; | |||
1273 | case Qualifiers::OCL_Weak: | |||
1274 | Flag = 2; | |||
1275 | break; | |||
1276 | case Qualifiers::OCL_ExplicitNone: | |||
1277 | Flag = 3; | |||
1278 | break; | |||
1279 | case Qualifiers::OCL_None: | |||
1280 | case Qualifiers::OCL_Autoreleasing: | |||
1281 | assert(Ownership != Qualifiers::OCL_Autoreleasing)((Ownership != Qualifiers::OCL_Autoreleasing) ? static_cast< void> (0) : __assert_fail ("Ownership != Qualifiers::OCL_Autoreleasing" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1281, __PRETTY_FUNCTION__)); | |||
1282 | Flag = 0; | |||
1283 | } | |||
1284 | return Flag; | |||
1285 | } | |||
1286 | llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames, | |||
1287 | ArrayRef<llvm::Constant *> IvarTypes, | |||
1288 | ArrayRef<llvm::Constant *> IvarOffsets, | |||
1289 | ArrayRef<llvm::Constant *> IvarAlign, | |||
1290 | ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership) override { | |||
1291 | llvm_unreachable("Method should not be called!")::llvm::llvm_unreachable_internal("Method should not be called!" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1291); | |||
1292 | } | |||
1293 | ||||
1294 | llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName) override { | |||
1295 | std::string Name = SymbolForProtocol(ProtocolName); | |||
1296 | auto *GV = TheModule.getGlobalVariable(Name); | |||
1297 | if (!GV) { | |||
1298 | // Emit a placeholder symbol. | |||
1299 | GV = new llvm::GlobalVariable(TheModule, ProtocolTy, false, | |||
1300 | llvm::GlobalValue::ExternalLinkage, nullptr, Name); | |||
1301 | GV->setAlignment(CGM.getPointerAlign().getAsAlign()); | |||
1302 | } | |||
1303 | return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy); | |||
1304 | } | |||
1305 | ||||
1306 | /// Existing protocol references. | |||
1307 | llvm::StringMap<llvm::Constant*> ExistingProtocolRefs; | |||
1308 | ||||
1309 | llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, | |||
1310 | const ObjCProtocolDecl *PD) override { | |||
1311 | auto Name = PD->getNameAsString(); | |||
1312 | auto *&Ref = ExistingProtocolRefs[Name]; | |||
1313 | if (!Ref) { | |||
1314 | auto *&Protocol = ExistingProtocols[Name]; | |||
1315 | if (!Protocol) | |||
1316 | Protocol = GenerateProtocolRef(PD); | |||
1317 | std::string RefName = SymbolForProtocolRef(Name); | |||
1318 | assert(!TheModule.getGlobalVariable(RefName))((!TheModule.getGlobalVariable(RefName)) ? static_cast<void > (0) : __assert_fail ("!TheModule.getGlobalVariable(RefName)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1318, __PRETTY_FUNCTION__)); | |||
1319 | // Emit a reference symbol. | |||
1320 | auto GV = new llvm::GlobalVariable(TheModule, ProtocolPtrTy, | |||
1321 | false, llvm::GlobalValue::LinkOnceODRLinkage, | |||
1322 | llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName); | |||
1323 | GV->setComdat(TheModule.getOrInsertComdat(RefName)); | |||
1324 | GV->setSection(sectionName<ProtocolReferenceSection>()); | |||
1325 | GV->setAlignment(CGM.getPointerAlign().getAsAlign()); | |||
1326 | Ref = GV; | |||
1327 | } | |||
1328 | EmittedProtocolRef = true; | |||
1329 | return CGF.Builder.CreateAlignedLoad(Ref, CGM.getPointerAlign()); | |||
1330 | } | |||
1331 | ||||
1332 | llvm::Constant *GenerateProtocolList(ArrayRef<llvm::Constant*> Protocols) { | |||
1333 | llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy, | |||
1334 | Protocols.size()); | |||
1335 | llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, | |||
1336 | Protocols); | |||
1337 | ConstantInitBuilder builder(CGM); | |||
1338 | auto ProtocolBuilder = builder.beginStruct(); | |||
1339 | ProtocolBuilder.addNullPointer(PtrTy); | |||
1340 | ProtocolBuilder.addInt(SizeTy, Protocols.size()); | |||
1341 | ProtocolBuilder.add(ProtocolArray); | |||
1342 | return ProtocolBuilder.finishAndCreateGlobal(".objc_protocol_list", | |||
1343 | CGM.getPointerAlign(), false, llvm::GlobalValue::InternalLinkage); | |||
1344 | } | |||
1345 | ||||
1346 | void GenerateProtocol(const ObjCProtocolDecl *PD) override { | |||
1347 | // Do nothing - we only emit referenced protocols. | |||
1348 | } | |||
1349 | llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) { | |||
1350 | std::string ProtocolName = PD->getNameAsString(); | |||
1351 | auto *&Protocol = ExistingProtocols[ProtocolName]; | |||
1352 | if (Protocol) | |||
1353 | return Protocol; | |||
1354 | ||||
1355 | EmittedProtocol = true; | |||
1356 | ||||
1357 | auto SymName = SymbolForProtocol(ProtocolName); | |||
1358 | auto *OldGV = TheModule.getGlobalVariable(SymName); | |||
1359 | ||||
1360 | // Use the protocol definition, if there is one. | |||
1361 | if (const ObjCProtocolDecl *Def = PD->getDefinition()) | |||
1362 | PD = Def; | |||
1363 | else { | |||
1364 | // If there is no definition, then create an external linkage symbol and | |||
1365 | // hope that someone else fills it in for us (and fail to link if they | |||
1366 | // don't). | |||
1367 | assert(!OldGV)((!OldGV) ? static_cast<void> (0) : __assert_fail ("!OldGV" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1367, __PRETTY_FUNCTION__)); | |||
1368 | Protocol = new llvm::GlobalVariable(TheModule, ProtocolTy, | |||
1369 | /*isConstant*/false, | |||
1370 | llvm::GlobalValue::ExternalLinkage, nullptr, SymName); | |||
1371 | return Protocol; | |||
1372 | } | |||
1373 | ||||
1374 | SmallVector<llvm::Constant*, 16> Protocols; | |||
1375 | for (const auto *PI : PD->protocols()) | |||
1376 | Protocols.push_back( | |||
1377 | llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI), | |||
1378 | ProtocolPtrTy)); | |||
1379 | llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); | |||
1380 | ||||
1381 | // Collect information about methods | |||
1382 | llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList; | |||
1383 | llvm::Constant *ClassMethodList, *OptionalClassMethodList; | |||
1384 | EmitProtocolMethodList(PD->instance_methods(), InstanceMethodList, | |||
1385 | OptionalInstanceMethodList); | |||
1386 | EmitProtocolMethodList(PD->class_methods(), ClassMethodList, | |||
1387 | OptionalClassMethodList); | |||
1388 | ||||
1389 | // The isa pointer must be set to a magic number so the runtime knows it's | |||
1390 | // the correct layout. | |||
1391 | ConstantInitBuilder builder(CGM); | |||
1392 | auto ProtocolBuilder = builder.beginStruct(); | |||
1393 | ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr( | |||
1394 | llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy)); | |||
1395 | ProtocolBuilder.add(MakeConstantString(ProtocolName)); | |||
1396 | ProtocolBuilder.add(ProtocolList); | |||
1397 | ProtocolBuilder.add(InstanceMethodList); | |||
1398 | ProtocolBuilder.add(ClassMethodList); | |||
1399 | ProtocolBuilder.add(OptionalInstanceMethodList); | |||
1400 | ProtocolBuilder.add(OptionalClassMethodList); | |||
1401 | // Required instance properties | |||
1402 | ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, false, false)); | |||
1403 | // Optional instance properties | |||
1404 | ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, false, true)); | |||
1405 | // Required class properties | |||
1406 | ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, true, false)); | |||
1407 | // Optional class properties | |||
1408 | ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, true, true)); | |||
1409 | ||||
1410 | auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName, | |||
1411 | CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage); | |||
1412 | GV->setSection(sectionName<ProtocolSection>()); | |||
1413 | GV->setComdat(TheModule.getOrInsertComdat(SymName)); | |||
1414 | if (OldGV) { | |||
1415 | OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV, | |||
1416 | OldGV->getType())); | |||
1417 | OldGV->removeFromParent(); | |||
1418 | GV->setName(SymName); | |||
1419 | } | |||
1420 | Protocol = GV; | |||
1421 | return GV; | |||
1422 | } | |||
1423 | llvm::Constant *EnforceType(llvm::Constant *Val, llvm::Type *Ty) { | |||
1424 | if (Val->getType() == Ty) | |||
1425 | return Val; | |||
1426 | return llvm::ConstantExpr::getBitCast(Val, Ty); | |||
1427 | } | |||
1428 | llvm::Value *GetTypedSelector(CodeGenFunction &CGF, Selector Sel, | |||
1429 | const std::string &TypeEncoding) override { | |||
1430 | return GetConstantSelector(Sel, TypeEncoding); | |||
1431 | } | |||
1432 | llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) { | |||
1433 | if (TypeEncoding.empty()) | |||
1434 | return NULLPtr; | |||
1435 | std::string MangledTypes = TypeEncoding; | |||
1436 | std::replace(MangledTypes.begin(), MangledTypes.end(), | |||
1437 | '@', '\1'); | |||
1438 | std::string TypesVarName = ".objc_sel_types_" + MangledTypes; | |||
1439 | auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName); | |||
1440 | if (!TypesGlobal) { | |||
1441 | llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext, | |||
1442 | TypeEncoding); | |||
1443 | auto *GV = new llvm::GlobalVariable(TheModule, Init->getType(), | |||
1444 | true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName); | |||
1445 | GV->setComdat(TheModule.getOrInsertComdat(TypesVarName)); | |||
1446 | GV->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1447 | TypesGlobal = GV; | |||
1448 | } | |||
1449 | return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(), | |||
1450 | TypesGlobal, Zeros); | |||
1451 | } | |||
1452 | llvm::Constant *GetConstantSelector(Selector Sel, | |||
1453 | const std::string &TypeEncoding) override { | |||
1454 | // @ is used as a special character in symbol names (used for symbol | |||
1455 | // versioning), so mangle the name to not include it. Replace it with a | |||
1456 | // character that is not a valid type encoding character (and, being | |||
1457 | // non-printable, never will be!) | |||
1458 | std::string MangledTypes = TypeEncoding; | |||
1459 | std::replace(MangledTypes.begin(), MangledTypes.end(), | |||
1460 | '@', '\1'); | |||
1461 | auto SelVarName = (StringRef(".objc_selector_") + Sel.getAsString() + "_" + | |||
1462 | MangledTypes).str(); | |||
1463 | if (auto *GV = TheModule.getNamedGlobal(SelVarName)) | |||
1464 | return EnforceType(GV, SelectorTy); | |||
1465 | ConstantInitBuilder builder(CGM); | |||
1466 | auto SelBuilder = builder.beginStruct(); | |||
1467 | SelBuilder.add(ExportUniqueString(Sel.getAsString(), ".objc_sel_name_", | |||
1468 | true)); | |||
1469 | SelBuilder.add(GetTypeString(TypeEncoding)); | |||
1470 | auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName, | |||
1471 | CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage); | |||
1472 | GV->setComdat(TheModule.getOrInsertComdat(SelVarName)); | |||
1473 | GV->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1474 | GV->setSection(sectionName<SelectorSection>()); | |||
1475 | auto *SelVal = EnforceType(GV, SelectorTy); | |||
1476 | return SelVal; | |||
1477 | } | |||
1478 | llvm::StructType *emptyStruct = nullptr; | |||
1479 | ||||
1480 | /// Return pointers to the start and end of a section. On ELF platforms, we | |||
1481 | /// use the __start_ and __stop_ symbols that GNU-compatible linkers will set | |||
1482 | /// to the start and end of section names, as long as those section names are | |||
1483 | /// valid identifiers and the symbols are referenced but not defined. On | |||
1484 | /// Windows, we use the fact that MSVC-compatible linkers will lexically sort | |||
1485 | /// by subsections and place everything that we want to reference in a middle | |||
1486 | /// subsection and then insert zero-sized symbols in subsections a and z. | |||
1487 | std::pair<llvm::Constant*,llvm::Constant*> | |||
1488 | GetSectionBounds(StringRef Section) { | |||
1489 | if (CGM.getTriple().isOSBinFormatCOFF()) { | |||
1490 | if (emptyStruct == nullptr) { | |||
1491 | emptyStruct = llvm::StructType::create(VMContext, ".objc_section_sentinel"); | |||
1492 | emptyStruct->setBody({}, /*isPacked*/true); | |||
1493 | } | |||
1494 | auto ZeroInit = llvm::Constant::getNullValue(emptyStruct); | |||
1495 | auto Sym = [&](StringRef Prefix, StringRef SecSuffix) { | |||
1496 | auto *Sym = new llvm::GlobalVariable(TheModule, emptyStruct, | |||
1497 | /*isConstant*/false, | |||
1498 | llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix + | |||
1499 | Section); | |||
1500 | Sym->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1501 | Sym->setSection((Section + SecSuffix).str()); | |||
1502 | Sym->setComdat(TheModule.getOrInsertComdat((Prefix + | |||
1503 | Section).str())); | |||
1504 | Sym->setAlignment(CGM.getPointerAlign().getAsAlign()); | |||
1505 | return Sym; | |||
1506 | }; | |||
1507 | return { Sym("__start_", "$a"), Sym("__stop", "$z") }; | |||
1508 | } | |||
1509 | auto *Start = new llvm::GlobalVariable(TheModule, PtrTy, | |||
1510 | /*isConstant*/false, | |||
1511 | llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__start_") + | |||
1512 | Section); | |||
1513 | Start->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1514 | auto *Stop = new llvm::GlobalVariable(TheModule, PtrTy, | |||
1515 | /*isConstant*/false, | |||
1516 | llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__stop_") + | |||
1517 | Section); | |||
1518 | Stop->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1519 | return { Start, Stop }; | |||
1520 | } | |||
1521 | CatchTypeInfo getCatchAllTypeInfo() override { | |||
1522 | return CGM.getCXXABI().getCatchAllTypeInfo(); | |||
1523 | } | |||
1524 | llvm::Function *ModuleInitFunction() override { | |||
1525 | llvm::Function *LoadFunction = llvm::Function::Create( | |||
1526 | llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false), | |||
1527 | llvm::GlobalValue::LinkOnceODRLinkage, ".objcv2_load_function", | |||
1528 | &TheModule); | |||
1529 | LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1530 | LoadFunction->setComdat(TheModule.getOrInsertComdat(".objcv2_load_function")); | |||
1531 | ||||
1532 | llvm::BasicBlock *EntryBB = | |||
1533 | llvm::BasicBlock::Create(VMContext, "entry", LoadFunction); | |||
1534 | CGBuilderTy B(CGM, VMContext); | |||
1535 | B.SetInsertPoint(EntryBB); | |||
1536 | ConstantInitBuilder builder(CGM); | |||
1537 | auto InitStructBuilder = builder.beginStruct(); | |||
1538 | InitStructBuilder.addInt(Int64Ty, 0); | |||
1539 | auto §ionVec = CGM.getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames; | |||
1540 | for (auto *s : sectionVec) { | |||
1541 | auto bounds = GetSectionBounds(s); | |||
1542 | InitStructBuilder.add(bounds.first); | |||
1543 | InitStructBuilder.add(bounds.second); | |||
1544 | } | |||
1545 | auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init", | |||
1546 | CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage); | |||
1547 | InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1548 | InitStruct->setComdat(TheModule.getOrInsertComdat(".objc_init")); | |||
1549 | ||||
1550 | CallRuntimeFunction(B, "__objc_load", {InitStruct});; | |||
1551 | B.CreateRetVoid(); | |||
1552 | // Make sure that the optimisers don't delete this function. | |||
1553 | CGM.addCompilerUsedGlobal(LoadFunction); | |||
1554 | // FIXME: Currently ELF only! | |||
1555 | // We have to do this by hand, rather than with @llvm.ctors, so that the | |||
1556 | // linker can remove the duplicate invocations. | |||
1557 | auto *InitVar = new llvm::GlobalVariable(TheModule, LoadFunction->getType(), | |||
1558 | /*isConstant*/true, llvm::GlobalValue::LinkOnceAnyLinkage, | |||
1559 | LoadFunction, ".objc_ctor"); | |||
1560 | // Check that this hasn't been renamed. This shouldn't happen, because | |||
1561 | // this function should be called precisely once. | |||
1562 | assert(InitVar->getName() == ".objc_ctor")((InitVar->getName() == ".objc_ctor") ? static_cast<void > (0) : __assert_fail ("InitVar->getName() == \".objc_ctor\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1562, __PRETTY_FUNCTION__)); | |||
1563 | // In Windows, initialisers are sorted by the suffix. XCL is for library | |||
1564 | // initialisers, which run before user initialisers. We are running | |||
1565 | // Objective-C loads at the end of library load. This means +load methods | |||
1566 | // will run before any other static constructors, but that static | |||
1567 | // constructors can see a fully initialised Objective-C state. | |||
1568 | if (CGM.getTriple().isOSBinFormatCOFF()) | |||
1569 | InitVar->setSection(".CRT$XCLz"); | |||
1570 | else | |||
1571 | { | |||
1572 | if (CGM.getCodeGenOpts().UseInitArray) | |||
1573 | InitVar->setSection(".init_array"); | |||
1574 | else | |||
1575 | InitVar->setSection(".ctors"); | |||
1576 | } | |||
1577 | InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1578 | InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor")); | |||
1579 | CGM.addUsedGlobal(InitVar); | |||
1580 | for (auto *C : Categories) { | |||
1581 | auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts()); | |||
1582 | Cat->setSection(sectionName<CategorySection>()); | |||
1583 | CGM.addUsedGlobal(Cat); | |||
1584 | } | |||
1585 | auto createNullGlobal = [&](StringRef Name, ArrayRef<llvm::Constant*> Init, | |||
1586 | StringRef Section) { | |||
1587 | auto nullBuilder = builder.beginStruct(); | |||
1588 | for (auto *F : Init) | |||
1589 | nullBuilder.add(F); | |||
1590 | auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.getPointerAlign(), | |||
1591 | false, llvm::GlobalValue::LinkOnceODRLinkage); | |||
1592 | GV->setSection(Section); | |||
1593 | GV->setComdat(TheModule.getOrInsertComdat(Name)); | |||
1594 | GV->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1595 | CGM.addUsedGlobal(GV); | |||
1596 | return GV; | |||
1597 | }; | |||
1598 | for (auto clsAlias : ClassAliases) | |||
1599 | createNullGlobal(std::string(".objc_class_alias") + | |||
1600 | clsAlias.second, { MakeConstantString(clsAlias.second), | |||
1601 | GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>()); | |||
1602 | // On ELF platforms, add a null value for each special section so that we | |||
1603 | // can always guarantee that the _start and _stop symbols will exist and be | |||
1604 | // meaningful. This is not required on COFF platforms, where our start and | |||
1605 | // stop symbols will create the section. | |||
1606 | if (!CGM.getTriple().isOSBinFormatCOFF()) { | |||
1607 | createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr}, | |||
1608 | sectionName<SelectorSection>()); | |||
1609 | if (Categories.empty()) | |||
1610 | createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr, | |||
1611 | NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr}, | |||
1612 | sectionName<CategorySection>()); | |||
1613 | if (!EmittedClass) { | |||
1614 | createNullGlobal(".objc_null_cls_init_ref", NULLPtr, | |||
1615 | sectionName<ClassSection>()); | |||
1616 | createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr }, | |||
1617 | sectionName<ClassReferenceSection>()); | |||
1618 | } | |||
1619 | if (!EmittedProtocol) | |||
1620 | createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr, | |||
1621 | NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, | |||
1622 | NULLPtr}, sectionName<ProtocolSection>()); | |||
1623 | if (!EmittedProtocolRef) | |||
1624 | createNullGlobal(".objc_null_protocol_ref", {NULLPtr}, | |||
1625 | sectionName<ProtocolReferenceSection>()); | |||
1626 | if (ClassAliases.empty()) | |||
1627 | createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr }, | |||
1628 | sectionName<ClassAliasSection>()); | |||
1629 | if (ConstantStrings.empty()) { | |||
1630 | auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0); | |||
1631 | createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero, | |||
1632 | i32Zero, i32Zero, i32Zero, NULLPtr }, | |||
1633 | sectionName<ConstantStringSection>()); | |||
1634 | } | |||
1635 | } | |||
1636 | ConstantStrings.clear(); | |||
1637 | Categories.clear(); | |||
1638 | Classes.clear(); | |||
1639 | ||||
1640 | if (EarlyInitList.size() > 0) { | |||
1641 | auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy, | |||
1642 | {}), llvm::GlobalValue::InternalLinkage, ".objc_early_init", | |||
1643 | &CGM.getModule()); | |||
1644 | llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry", | |||
1645 | Init)); | |||
1646 | for (const auto &lateInit : EarlyInitList) { | |||
1647 | auto *global = TheModule.getGlobalVariable(lateInit.first); | |||
1648 | if (global) { | |||
1649 | b.CreateAlignedStore(global, | |||
1650 | b.CreateStructGEP(lateInit.second.first, lateInit.second.second), CGM.getPointerAlign().getQuantity()); | |||
1651 | } | |||
1652 | } | |||
1653 | b.CreateRetVoid(); | |||
1654 | // We can't use the normal LLVM global initialisation array, because we | |||
1655 | // need to specify that this runs early in library initialisation. | |||
1656 | auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), | |||
1657 | /*isConstant*/true, llvm::GlobalValue::InternalLinkage, | |||
1658 | Init, ".objc_early_init_ptr"); | |||
1659 | InitVar->setSection(".CRT$XCLb"); | |||
1660 | CGM.addUsedGlobal(InitVar); | |||
1661 | } | |||
1662 | return nullptr; | |||
1663 | } | |||
1664 | /// In the v2 ABI, ivar offset variables use the type encoding in their name | |||
1665 | /// to trigger linker failures if the types don't match. | |||
1666 | std::string GetIVarOffsetVariableName(const ObjCInterfaceDecl *ID, | |||
1667 | const ObjCIvarDecl *Ivar) override { | |||
1668 | std::string TypeEncoding; | |||
1669 | CGM.getContext().getObjCEncodingForType(Ivar->getType(), TypeEncoding); | |||
1670 | // Prevent the @ from being interpreted as a symbol version. | |||
1671 | std::replace(TypeEncoding.begin(), TypeEncoding.end(), | |||
1672 | '@', '\1'); | |||
1673 | const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() | |||
1674 | + '.' + Ivar->getNameAsString() + '.' + TypeEncoding; | |||
1675 | return Name; | |||
1676 | } | |||
1677 | llvm::Value *EmitIvarOffset(CodeGenFunction &CGF, | |||
1678 | const ObjCInterfaceDecl *Interface, | |||
1679 | const ObjCIvarDecl *Ivar) override { | |||
1680 | const std::string Name = GetIVarOffsetVariableName(Ivar->getContainingInterface(), Ivar); | |||
1681 | llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); | |||
1682 | if (!IvarOffsetPointer) | |||
1683 | IvarOffsetPointer = new llvm::GlobalVariable(TheModule, IntTy, false, | |||
1684 | llvm::GlobalValue::ExternalLinkage, nullptr, Name); | |||
1685 | CharUnits Align = CGM.getIntAlign(); | |||
1686 | llvm::Value *Offset = CGF.Builder.CreateAlignedLoad(IvarOffsetPointer, Align); | |||
1687 | if (Offset->getType() != PtrDiffTy) | |||
1688 | Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); | |||
1689 | return Offset; | |||
1690 | } | |||
1691 | void GenerateClass(const ObjCImplementationDecl *OID) override { | |||
1692 | ASTContext &Context = CGM.getContext(); | |||
1693 | bool IsCOFF = CGM.getTriple().isOSBinFormatCOFF(); | |||
1694 | ||||
1695 | // Get the class name | |||
1696 | ObjCInterfaceDecl *classDecl = | |||
1697 | const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); | |||
1698 | std::string className = classDecl->getNameAsString(); | |||
1699 | auto *classNameConstant = MakeConstantString(className); | |||
1700 | ||||
1701 | ConstantInitBuilder builder(CGM); | |||
1702 | auto metaclassFields = builder.beginStruct(); | |||
1703 | // struct objc_class *isa; | |||
1704 | metaclassFields.addNullPointer(PtrTy); | |||
1705 | // struct objc_class *super_class; | |||
1706 | metaclassFields.addNullPointer(PtrTy); | |||
1707 | // const char *name; | |||
1708 | metaclassFields.add(classNameConstant); | |||
1709 | // long version; | |||
1710 | metaclassFields.addInt(LongTy, 0); | |||
1711 | // unsigned long info; | |||
1712 | // objc_class_flag_meta | |||
1713 | metaclassFields.addInt(LongTy, 1); | |||
1714 | // long instance_size; | |||
1715 | // Setting this to zero is consistent with the older ABI, but it might be | |||
1716 | // more sensible to set this to sizeof(struct objc_class) | |||
1717 | metaclassFields.addInt(LongTy, 0); | |||
1718 | // struct objc_ivar_list *ivars; | |||
1719 | metaclassFields.addNullPointer(PtrTy); | |||
1720 | // struct objc_method_list *methods | |||
1721 | // FIXME: Almost identical code is copied and pasted below for the | |||
1722 | // class, but refactoring it cleanly requires C++14 generic lambdas. | |||
1723 | if (OID->classmeth_begin() == OID->classmeth_end()) | |||
1724 | metaclassFields.addNullPointer(PtrTy); | |||
1725 | else { | |||
1726 | SmallVector<ObjCMethodDecl*, 16> ClassMethods; | |||
1727 | ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(), | |||
1728 | OID->classmeth_end()); | |||
1729 | metaclassFields.addBitCast( | |||
1730 | GenerateMethodList(className, "", ClassMethods, true), | |||
1731 | PtrTy); | |||
1732 | } | |||
1733 | // void *dtable; | |||
1734 | metaclassFields.addNullPointer(PtrTy); | |||
1735 | // IMP cxx_construct; | |||
1736 | metaclassFields.addNullPointer(PtrTy); | |||
1737 | // IMP cxx_destruct; | |||
1738 | metaclassFields.addNullPointer(PtrTy); | |||
1739 | // struct objc_class *subclass_list | |||
1740 | metaclassFields.addNullPointer(PtrTy); | |||
1741 | // struct objc_class *sibling_class | |||
1742 | metaclassFields.addNullPointer(PtrTy); | |||
1743 | // struct objc_protocol_list *protocols; | |||
1744 | metaclassFields.addNullPointer(PtrTy); | |||
1745 | // struct reference_list *extra_data; | |||
1746 | metaclassFields.addNullPointer(PtrTy); | |||
1747 | // long abi_version; | |||
1748 | metaclassFields.addInt(LongTy, 0); | |||
1749 | // struct objc_property_list *properties | |||
1750 | metaclassFields.add(GeneratePropertyList(OID, classDecl, /*isClassProperty*/true)); | |||
1751 | ||||
1752 | auto *metaclass = metaclassFields.finishAndCreateGlobal( | |||
1753 | ManglePublicSymbol("OBJC_METACLASS_") + className, | |||
1754 | CGM.getPointerAlign()); | |||
1755 | ||||
1756 | auto classFields = builder.beginStruct(); | |||
1757 | // struct objc_class *isa; | |||
1758 | classFields.add(metaclass); | |||
1759 | // struct objc_class *super_class; | |||
1760 | // Get the superclass name. | |||
1761 | const ObjCInterfaceDecl * SuperClassDecl = | |||
1762 | OID->getClassInterface()->getSuperClass(); | |||
1763 | llvm::Constant *SuperClass = nullptr; | |||
1764 | if (SuperClassDecl) { | |||
1765 | auto SuperClassName = SymbolForClass(SuperClassDecl->getNameAsString()); | |||
1766 | SuperClass = TheModule.getNamedGlobal(SuperClassName); | |||
1767 | if (!SuperClass) | |||
1768 | { | |||
1769 | SuperClass = new llvm::GlobalVariable(TheModule, PtrTy, false, | |||
1770 | llvm::GlobalValue::ExternalLinkage, nullptr, SuperClassName); | |||
1771 | if (IsCOFF) { | |||
1772 | auto Storage = llvm::GlobalValue::DefaultStorageClass; | |||
1773 | if (SuperClassDecl->hasAttr<DLLImportAttr>()) | |||
1774 | Storage = llvm::GlobalValue::DLLImportStorageClass; | |||
1775 | else if (SuperClassDecl->hasAttr<DLLExportAttr>()) | |||
1776 | Storage = llvm::GlobalValue::DLLExportStorageClass; | |||
1777 | ||||
1778 | cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage); | |||
1779 | } | |||
1780 | } | |||
1781 | if (!IsCOFF) | |||
1782 | classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy)); | |||
1783 | else | |||
1784 | classFields.addNullPointer(PtrTy); | |||
1785 | } else | |||
1786 | classFields.addNullPointer(PtrTy); | |||
1787 | // const char *name; | |||
1788 | classFields.add(classNameConstant); | |||
1789 | // long version; | |||
1790 | classFields.addInt(LongTy, 0); | |||
1791 | // unsigned long info; | |||
1792 | // !objc_class_flag_meta | |||
1793 | classFields.addInt(LongTy, 0); | |||
1794 | // long instance_size; | |||
1795 | int superInstanceSize = !SuperClassDecl ? 0 : | |||
1796 | Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity(); | |||
1797 | // Instance size is negative for classes that have not yet had their ivar | |||
1798 | // layout calculated. | |||
1799 | classFields.addInt(LongTy, | |||
1800 | 0 - (Context.getASTObjCImplementationLayout(OID).getSize().getQuantity() - | |||
1801 | superInstanceSize)); | |||
1802 | ||||
1803 | if (classDecl->all_declared_ivar_begin() == nullptr) | |||
1804 | classFields.addNullPointer(PtrTy); | |||
1805 | else { | |||
1806 | int ivar_count = 0; | |||
1807 | for (const ObjCIvarDecl *IVD = classDecl->all_declared_ivar_begin(); IVD; | |||
1808 | IVD = IVD->getNextIvar()) ivar_count++; | |||
1809 | llvm::DataLayout td(&TheModule); | |||
1810 | // struct objc_ivar_list *ivars; | |||
1811 | ConstantInitBuilder b(CGM); | |||
1812 | auto ivarListBuilder = b.beginStruct(); | |||
1813 | // int count; | |||
1814 | ivarListBuilder.addInt(IntTy, ivar_count); | |||
1815 | // size_t size; | |||
1816 | llvm::StructType *ObjCIvarTy = llvm::StructType::get( | |||
1817 | PtrToInt8Ty, | |||
1818 | PtrToInt8Ty, | |||
1819 | PtrToInt8Ty, | |||
1820 | Int32Ty, | |||
1821 | Int32Ty); | |||
1822 | ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) / | |||
1823 | CGM.getContext().getCharWidth()); | |||
1824 | // struct objc_ivar ivars[] | |||
1825 | auto ivarArrayBuilder = ivarListBuilder.beginArray(); | |||
1826 | for (const ObjCIvarDecl *IVD = classDecl->all_declared_ivar_begin(); IVD; | |||
1827 | IVD = IVD->getNextIvar()) { | |||
1828 | auto ivarTy = IVD->getType(); | |||
1829 | auto ivarBuilder = ivarArrayBuilder.beginStruct(); | |||
1830 | // const char *name; | |||
1831 | ivarBuilder.add(MakeConstantString(IVD->getNameAsString())); | |||
1832 | // const char *type; | |||
1833 | std::string TypeStr; | |||
1834 | //Context.getObjCEncodingForType(ivarTy, TypeStr, IVD, true); | |||
1835 | Context.getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, ivarTy, TypeStr, true); | |||
1836 | ivarBuilder.add(MakeConstantString(TypeStr)); | |||
1837 | // int *offset; | |||
1838 | uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD); | |||
1839 | uint64_t Offset = BaseOffset - superInstanceSize; | |||
1840 | llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset); | |||
1841 | std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD); | |||
1842 | llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName); | |||
1843 | if (OffsetVar) | |||
1844 | OffsetVar->setInitializer(OffsetValue); | |||
1845 | else | |||
1846 | OffsetVar = new llvm::GlobalVariable(TheModule, IntTy, | |||
1847 | false, llvm::GlobalValue::ExternalLinkage, | |||
1848 | OffsetValue, OffsetName); | |||
1849 | auto ivarVisibility = | |||
1850 | (IVD->getAccessControl() == ObjCIvarDecl::Private || | |||
1851 | IVD->getAccessControl() == ObjCIvarDecl::Package || | |||
1852 | classDecl->getVisibility() == HiddenVisibility) ? | |||
1853 | llvm::GlobalValue::HiddenVisibility : | |||
1854 | llvm::GlobalValue::DefaultVisibility; | |||
1855 | OffsetVar->setVisibility(ivarVisibility); | |||
1856 | ivarBuilder.add(OffsetVar); | |||
1857 | // Ivar size | |||
1858 | ivarBuilder.addInt(Int32Ty, | |||
1859 | CGM.getContext().getTypeSizeInChars(ivarTy).getQuantity()); | |||
1860 | // Alignment will be stored as a base-2 log of the alignment. | |||
1861 | unsigned align = | |||
1862 | llvm::Log2_32(Context.getTypeAlignInChars(ivarTy).getQuantity()); | |||
1863 | // Objects that require more than 2^64-byte alignment should be impossible! | |||
1864 | assert(align < 64)((align < 64) ? static_cast<void> (0) : __assert_fail ("align < 64", "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1864, __PRETTY_FUNCTION__)); | |||
1865 | // uint32_t flags; | |||
1866 | // Bits 0-1 are ownership. | |||
1867 | // Bit 2 indicates an extended type encoding | |||
1868 | // Bits 3-8 contain log2(aligment) | |||
1869 | ivarBuilder.addInt(Int32Ty, | |||
1870 | (align << 3) | (1<<2) | | |||
1871 | FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime())); | |||
1872 | ivarBuilder.finishAndAddTo(ivarArrayBuilder); | |||
1873 | } | |||
1874 | ivarArrayBuilder.finishAndAddTo(ivarListBuilder); | |||
1875 | auto ivarList = ivarListBuilder.finishAndCreateGlobal(".objc_ivar_list", | |||
1876 | CGM.getPointerAlign(), /*constant*/ false, | |||
1877 | llvm::GlobalValue::PrivateLinkage); | |||
1878 | classFields.add(ivarList); | |||
1879 | } | |||
1880 | // struct objc_method_list *methods | |||
1881 | SmallVector<const ObjCMethodDecl*, 16> InstanceMethods; | |||
1882 | InstanceMethods.insert(InstanceMethods.begin(), OID->instmeth_begin(), | |||
1883 | OID->instmeth_end()); | |||
1884 | for (auto *propImpl : OID->property_impls()) | |||
1885 | if (propImpl->getPropertyImplementation() == | |||
1886 | ObjCPropertyImplDecl::Synthesize) { | |||
1887 | auto addIfExists = [&](const ObjCMethodDecl *OMD) { | |||
1888 | if (OMD && OMD->hasBody()) | |||
1889 | InstanceMethods.push_back(OMD); | |||
1890 | }; | |||
1891 | addIfExists(propImpl->getGetterMethodDecl()); | |||
1892 | addIfExists(propImpl->getSetterMethodDecl()); | |||
1893 | } | |||
1894 | ||||
1895 | if (InstanceMethods.size() == 0) | |||
1896 | classFields.addNullPointer(PtrTy); | |||
1897 | else | |||
1898 | classFields.addBitCast( | |||
1899 | GenerateMethodList(className, "", InstanceMethods, false), | |||
1900 | PtrTy); | |||
1901 | // void *dtable; | |||
1902 | classFields.addNullPointer(PtrTy); | |||
1903 | // IMP cxx_construct; | |||
1904 | classFields.addNullPointer(PtrTy); | |||
1905 | // IMP cxx_destruct; | |||
1906 | classFields.addNullPointer(PtrTy); | |||
1907 | // struct objc_class *subclass_list | |||
1908 | classFields.addNullPointer(PtrTy); | |||
1909 | // struct objc_class *sibling_class | |||
1910 | classFields.addNullPointer(PtrTy); | |||
1911 | // struct objc_protocol_list *protocols; | |||
1912 | SmallVector<llvm::Constant*, 16> Protocols; | |||
1913 | for (const auto *I : classDecl->protocols()) | |||
1914 | Protocols.push_back( | |||
1915 | llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I), | |||
1916 | ProtocolPtrTy)); | |||
1917 | if (Protocols.empty()) | |||
1918 | classFields.addNullPointer(PtrTy); | |||
1919 | else | |||
1920 | classFields.add(GenerateProtocolList(Protocols)); | |||
1921 | // struct reference_list *extra_data; | |||
1922 | classFields.addNullPointer(PtrTy); | |||
1923 | // long abi_version; | |||
1924 | classFields.addInt(LongTy, 0); | |||
1925 | // struct objc_property_list *properties | |||
1926 | classFields.add(GeneratePropertyList(OID, classDecl)); | |||
1927 | ||||
1928 | auto *classStruct = | |||
1929 | classFields.finishAndCreateGlobal(SymbolForClass(className), | |||
1930 | CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage); | |||
1931 | ||||
1932 | auto *classRefSymbol = GetClassVar(className); | |||
1933 | classRefSymbol->setSection(sectionName<ClassReferenceSection>()); | |||
1934 | classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy)); | |||
1935 | ||||
1936 | if (IsCOFF) { | |||
1937 | // we can't import a class struct. | |||
1938 | if (OID->getClassInterface()->hasAttr<DLLExportAttr>()) { | |||
1939 | cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); | |||
1940 | cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); | |||
1941 | } | |||
1942 | ||||
1943 | if (SuperClass) { | |||
1944 | std::pair<llvm::Constant*, int> v{classStruct, 1}; | |||
1945 | EarlyInitList.emplace_back(SuperClass->getName(), std::move(v)); | |||
1946 | } | |||
1947 | ||||
1948 | } | |||
1949 | ||||
1950 | ||||
1951 | // Resolve the class aliases, if they exist. | |||
1952 | // FIXME: Class pointer aliases shouldn't exist! | |||
1953 | if (ClassPtrAlias) { | |||
1954 | ClassPtrAlias->replaceAllUsesWith( | |||
1955 | llvm::ConstantExpr::getBitCast(classStruct, IdTy)); | |||
1956 | ClassPtrAlias->eraseFromParent(); | |||
1957 | ClassPtrAlias = nullptr; | |||
1958 | } | |||
1959 | if (auto Placeholder = | |||
1960 | TheModule.getNamedGlobal(SymbolForClass(className))) | |||
1961 | if (Placeholder != classStruct) { | |||
1962 | Placeholder->replaceAllUsesWith( | |||
1963 | llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType())); | |||
1964 | Placeholder->eraseFromParent(); | |||
1965 | classStruct->setName(SymbolForClass(className)); | |||
1966 | } | |||
1967 | if (MetaClassPtrAlias) { | |||
1968 | MetaClassPtrAlias->replaceAllUsesWith( | |||
1969 | llvm::ConstantExpr::getBitCast(metaclass, IdTy)); | |||
1970 | MetaClassPtrAlias->eraseFromParent(); | |||
1971 | MetaClassPtrAlias = nullptr; | |||
1972 | } | |||
1973 | assert(classStruct->getName() == SymbolForClass(className))((classStruct->getName() == SymbolForClass(className)) ? static_cast <void> (0) : __assert_fail ("classStruct->getName() == SymbolForClass(className)" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 1973, __PRETTY_FUNCTION__)); | |||
1974 | ||||
1975 | auto classInitRef = new llvm::GlobalVariable(TheModule, | |||
1976 | classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage, | |||
1977 | classStruct, ManglePublicSymbol("OBJC_INIT_CLASS_") + className); | |||
1978 | classInitRef->setSection(sectionName<ClassSection>()); | |||
1979 | CGM.addUsedGlobal(classInitRef); | |||
1980 | ||||
1981 | EmittedClass = true; | |||
1982 | } | |||
1983 | public: | |||
1984 | CGObjCGNUstep2(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) { | |||
1985 | MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, | |||
1986 | PtrToObjCSuperTy, SelectorTy); | |||
1987 | // struct objc_property | |||
1988 | // { | |||
1989 | // const char *name; | |||
1990 | // const char *attributes; | |||
1991 | // const char *type; | |||
1992 | // SEL getter; | |||
1993 | // SEL setter; | |||
1994 | // } | |||
1995 | PropertyMetadataTy = | |||
1996 | llvm::StructType::get(CGM.getLLVMContext(), | |||
1997 | { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty }); | |||
1998 | } | |||
1999 | ||||
2000 | }; | |||
2001 | ||||
2002 | const char *const CGObjCGNUstep2::SectionsBaseNames[8] = | |||
2003 | { | |||
2004 | "__objc_selectors", | |||
2005 | "__objc_classes", | |||
2006 | "__objc_class_refs", | |||
2007 | "__objc_cats", | |||
2008 | "__objc_protocols", | |||
2009 | "__objc_protocol_refs", | |||
2010 | "__objc_class_aliases", | |||
2011 | "__objc_constant_string" | |||
2012 | }; | |||
2013 | ||||
2014 | const char *const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] = | |||
2015 | { | |||
2016 | ".objcrt$SEL", | |||
2017 | ".objcrt$CLS", | |||
2018 | ".objcrt$CLR", | |||
2019 | ".objcrt$CAT", | |||
2020 | ".objcrt$PCL", | |||
2021 | ".objcrt$PCR", | |||
2022 | ".objcrt$CAL", | |||
2023 | ".objcrt$STR" | |||
2024 | }; | |||
2025 | ||||
2026 | /// Support for the ObjFW runtime. | |||
2027 | class CGObjCObjFW: public CGObjCGNU { | |||
2028 | protected: | |||
2029 | /// The GCC ABI message lookup function. Returns an IMP pointing to the | |||
2030 | /// method implementation for this message. | |||
2031 | LazyRuntimeFunction MsgLookupFn; | |||
2032 | /// stret lookup function. While this does not seem to make sense at the | |||
2033 | /// first look, this is required to call the correct forwarding function. | |||
2034 | LazyRuntimeFunction MsgLookupFnSRet; | |||
2035 | /// The GCC ABI superclass message lookup function. Takes a pointer to a | |||
2036 | /// structure describing the receiver and the class, and a selector as | |||
2037 | /// arguments. Returns the IMP for the corresponding method. | |||
2038 | LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet; | |||
2039 | ||||
2040 | llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, | |||
2041 | llvm::Value *cmd, llvm::MDNode *node, | |||
2042 | MessageSendInfo &MSI) override { | |||
2043 | CGBuilderTy &Builder = CGF.Builder; | |||
2044 | llvm::Value *args[] = { | |||
2045 | EnforceType(Builder, Receiver, IdTy), | |||
2046 | EnforceType(Builder, cmd, SelectorTy) }; | |||
2047 | ||||
2048 | llvm::CallBase *imp; | |||
2049 | if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) | |||
2050 | imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFnSRet, args); | |||
2051 | else | |||
2052 | imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); | |||
2053 | ||||
2054 | imp->setMetadata(msgSendMDKind, node); | |||
2055 | return imp; | |||
2056 | } | |||
2057 | ||||
2058 | llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, | |||
2059 | llvm::Value *cmd, MessageSendInfo &MSI) override { | |||
2060 | CGBuilderTy &Builder = CGF.Builder; | |||
2061 | llvm::Value *lookupArgs[] = { | |||
2062 | EnforceType(Builder, ObjCSuper.getPointer(), PtrToObjCSuperTy), cmd, | |||
2063 | }; | |||
2064 | ||||
2065 | if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) | |||
2066 | return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFnSRet, lookupArgs); | |||
2067 | else | |||
2068 | return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); | |||
2069 | } | |||
2070 | ||||
2071 | llvm::Value *GetClassNamed(CodeGenFunction &CGF, const std::string &Name, | |||
2072 | bool isWeak) override { | |||
2073 | if (isWeak) | |||
2074 | return CGObjCGNU::GetClassNamed(CGF, Name, isWeak); | |||
2075 | ||||
2076 | EmitClassRef(Name); | |||
2077 | std::string SymbolName = "_OBJC_CLASS_" + Name; | |||
2078 | llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName); | |||
2079 | if (!ClassSymbol) | |||
2080 | ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, | |||
2081 | llvm::GlobalValue::ExternalLinkage, | |||
2082 | nullptr, SymbolName); | |||
2083 | return ClassSymbol; | |||
2084 | } | |||
2085 | ||||
2086 | public: | |||
2087 | CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) { | |||
2088 | // IMP objc_msg_lookup(id, SEL); | |||
2089 | MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy); | |||
2090 | MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy, | |||
2091 | SelectorTy); | |||
2092 | // IMP objc_msg_lookup_super(struct objc_super*, SEL); | |||
2093 | MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, | |||
2094 | PtrToObjCSuperTy, SelectorTy); | |||
2095 | MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy, | |||
2096 | PtrToObjCSuperTy, SelectorTy); | |||
2097 | } | |||
2098 | }; | |||
2099 | } // end anonymous namespace | |||
2100 | ||||
2101 | /// Emits a reference to a dummy variable which is emitted with each class. | |||
2102 | /// This ensures that a linker error will be generated when trying to link | |||
2103 | /// together modules where a referenced class is not defined. | |||
2104 | void CGObjCGNU::EmitClassRef(const std::string &className) { | |||
2105 | std::string symbolRef = "__objc_class_ref_" + className; | |||
2106 | // Don't emit two copies of the same symbol | |||
2107 | if (TheModule.getGlobalVariable(symbolRef)) | |||
2108 | return; | |||
2109 | std::string symbolName = "__objc_class_name_" + className; | |||
2110 | llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName); | |||
2111 | if (!ClassSymbol) { | |||
2112 | ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, | |||
2113 | llvm::GlobalValue::ExternalLinkage, | |||
2114 | nullptr, symbolName); | |||
2115 | } | |||
2116 | new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true, | |||
2117 | llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef); | |||
2118 | } | |||
2119 | ||||
2120 | CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion, | |||
2121 | unsigned protocolClassVersion, unsigned classABI) | |||
2122 | : CGObjCRuntime(cgm), TheModule(CGM.getModule()), | |||
2123 | VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr), | |||
2124 | MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion), | |||
2125 | ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) { | |||
2126 | ||||
2127 | msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend"); | |||
2128 | usesSEHExceptions = | |||
2129 | cgm.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment(); | |||
2130 | ||||
2131 | CodeGenTypes &Types = CGM.getTypes(); | |||
2132 | IntTy = cast<llvm::IntegerType>( | |||
2133 | Types.ConvertType(CGM.getContext().IntTy)); | |||
2134 | LongTy = cast<llvm::IntegerType>( | |||
2135 | Types.ConvertType(CGM.getContext().LongTy)); | |||
2136 | SizeTy = cast<llvm::IntegerType>( | |||
2137 | Types.ConvertType(CGM.getContext().getSizeType())); | |||
2138 | PtrDiffTy = cast<llvm::IntegerType>( | |||
2139 | Types.ConvertType(CGM.getContext().getPointerDiffType())); | |||
2140 | BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy); | |||
2141 | ||||
2142 | Int8Ty = llvm::Type::getInt8Ty(VMContext); | |||
2143 | // C string type. Used in lots of places. | |||
2144 | PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); | |||
2145 | ProtocolPtrTy = llvm::PointerType::getUnqual( | |||
2146 | Types.ConvertType(CGM.getContext().getObjCProtoType())); | |||
2147 | ||||
2148 | Zeros[0] = llvm::ConstantInt::get(LongTy, 0); | |||
2149 | Zeros[1] = Zeros[0]; | |||
2150 | NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty); | |||
2151 | // Get the selector Type. | |||
2152 | QualType selTy = CGM.getContext().getObjCSelType(); | |||
2153 | if (QualType() == selTy) { | |||
2154 | SelectorTy = PtrToInt8Ty; | |||
2155 | } else { | |||
2156 | SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy)); | |||
2157 | } | |||
2158 | ||||
2159 | PtrToIntTy = llvm::PointerType::getUnqual(IntTy); | |||
2160 | PtrTy = PtrToInt8Ty; | |||
2161 | ||||
2162 | Int32Ty = llvm::Type::getInt32Ty(VMContext); | |||
2163 | Int64Ty = llvm::Type::getInt64Ty(VMContext); | |||
2164 | ||||
2165 | IntPtrTy = | |||
2166 | CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty; | |||
2167 | ||||
2168 | // Object type | |||
2169 | QualType UnqualIdTy = CGM.getContext().getObjCIdType(); | |||
2170 | ASTIdTy = CanQualType(); | |||
2171 | if (UnqualIdTy != QualType()) { | |||
2172 | ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy); | |||
2173 | IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); | |||
2174 | } else { | |||
2175 | IdTy = PtrToInt8Ty; | |||
2176 | } | |||
2177 | PtrToIdTy = llvm::PointerType::getUnqual(IdTy); | |||
2178 | ProtocolTy = llvm::StructType::get(IdTy, | |||
2179 | PtrToInt8Ty, // name | |||
2180 | PtrToInt8Ty, // protocols | |||
2181 | PtrToInt8Ty, // instance methods | |||
2182 | PtrToInt8Ty, // class methods | |||
2183 | PtrToInt8Ty, // optional instance methods | |||
2184 | PtrToInt8Ty, // optional class methods | |||
2185 | PtrToInt8Ty, // properties | |||
2186 | PtrToInt8Ty);// optional properties | |||
2187 | ||||
2188 | // struct objc_property_gsv1 | |||
2189 | // { | |||
2190 | // const char *name; | |||
2191 | // char attributes; | |||
2192 | // char attributes2; | |||
2193 | // char unused1; | |||
2194 | // char unused2; | |||
2195 | // const char *getter_name; | |||
2196 | // const char *getter_types; | |||
2197 | // const char *setter_name; | |||
2198 | // const char *setter_types; | |||
2199 | // } | |||
2200 | PropertyMetadataTy = llvm::StructType::get(CGM.getLLVMContext(), { | |||
2201 | PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, | |||
2202 | PtrToInt8Ty, PtrToInt8Ty }); | |||
2203 | ||||
2204 | ObjCSuperTy = llvm::StructType::get(IdTy, IdTy); | |||
2205 | PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy); | |||
2206 | ||||
2207 | llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); | |||
2208 | ||||
2209 | // void objc_exception_throw(id); | |||
2210 | ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy); | |||
2211 | ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy); | |||
2212 | // int objc_sync_enter(id); | |||
2213 | SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy); | |||
2214 | // int objc_sync_exit(id); | |||
2215 | SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy); | |||
2216 | ||||
2217 | // void objc_enumerationMutation (id) | |||
2218 | EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy, IdTy); | |||
2219 | ||||
2220 | // id objc_getProperty(id, SEL, ptrdiff_t, BOOL) | |||
2221 | GetPropertyFn.init(&CGM, "objc_getProperty", IdTy, IdTy, SelectorTy, | |||
2222 | PtrDiffTy, BoolTy); | |||
2223 | // void objc_setProperty(id, SEL, ptrdiff_t, id, BOOL, BOOL) | |||
2224 | SetPropertyFn.init(&CGM, "objc_setProperty", VoidTy, IdTy, SelectorTy, | |||
2225 | PtrDiffTy, IdTy, BoolTy, BoolTy); | |||
2226 | // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL) | |||
2227 | GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy, | |||
2228 | PtrDiffTy, BoolTy, BoolTy); | |||
2229 | // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL) | |||
2230 | SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy, | |||
2231 | PtrDiffTy, BoolTy, BoolTy); | |||
2232 | ||||
2233 | // IMP type | |||
2234 | llvm::Type *IMPArgs[] = { IdTy, SelectorTy }; | |||
2235 | IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs, | |||
2236 | true)); | |||
2237 | ||||
2238 | const LangOptions &Opts = CGM.getLangOpts(); | |||
2239 | if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount) | |||
2240 | RuntimeVersion = 10; | |||
2241 | ||||
2242 | // Don't bother initialising the GC stuff unless we're compiling in GC mode | |||
2243 | if (Opts.getGC() != LangOptions::NonGC) { | |||
2244 | // This is a bit of an hack. We should sort this out by having a proper | |||
2245 | // CGObjCGNUstep subclass for GC, but we may want to really support the old | |||
2246 | // ABI and GC added in ObjectiveC2.framework, so we fudge it a bit for now | |||
2247 | // Get selectors needed in GC mode | |||
2248 | RetainSel = GetNullarySelector("retain", CGM.getContext()); | |||
2249 | ReleaseSel = GetNullarySelector("release", CGM.getContext()); | |||
2250 | AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext()); | |||
2251 | ||||
2252 | // Get functions needed in GC mode | |||
2253 | ||||
2254 | // id objc_assign_ivar(id, id, ptrdiff_t); | |||
2255 | IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy); | |||
2256 | // id objc_assign_strongCast (id, id*) | |||
2257 | StrongCastAssignFn.init(&CGM, "objc_assign_strongCast", IdTy, IdTy, | |||
2258 | PtrToIdTy); | |||
2259 | // id objc_assign_global(id, id*); | |||
2260 | GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy); | |||
2261 | // id objc_assign_weak(id, id*); | |||
2262 | WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy); | |||
2263 | // id objc_read_weak(id*); | |||
2264 | WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy); | |||
2265 | // void *objc_memmove_collectable(void*, void *, size_t); | |||
2266 | MemMoveFn.init(&CGM, "objc_memmove_collectable", PtrTy, PtrTy, PtrTy, | |||
2267 | SizeTy); | |||
2268 | } | |||
2269 | } | |||
2270 | ||||
2271 | llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF, | |||
2272 | const std::string &Name, bool isWeak) { | |||
2273 | llvm::Constant *ClassName = MakeConstantString(Name); | |||
2274 | // With the incompatible ABI, this will need to be replaced with a direct | |||
2275 | // reference to the class symbol. For the compatible nonfragile ABI we are | |||
2276 | // still performing this lookup at run time but emitting the symbol for the | |||
2277 | // class externally so that we can make the switch later. | |||
2278 | // | |||
2279 | // Libobjc2 contains an LLVM pass that replaces calls to objc_lookup_class | |||
2280 | // with memoized versions or with static references if it's safe to do so. | |||
2281 | if (!isWeak) | |||
2282 | EmitClassRef(Name); | |||
2283 | ||||
2284 | llvm::FunctionCallee ClassLookupFn = CGM.CreateRuntimeFunction( | |||
2285 | llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), "objc_lookup_class"); | |||
2286 | return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName); | |||
2287 | } | |||
2288 | ||||
2289 | // This has to perform the lookup every time, since posing and related | |||
2290 | // techniques can modify the name -> class mapping. | |||
2291 | llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF, | |||
2292 | const ObjCInterfaceDecl *OID) { | |||
2293 | auto *Value = | |||
2294 | GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported()); | |||
2295 | if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value)) | |||
2296 | CGM.setGVProperties(ClassSymbol, OID); | |||
2297 | return Value; | |||
2298 | } | |||
2299 | ||||
2300 | llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { | |||
2301 | auto *Value = GetClassNamed(CGF, "NSAutoreleasePool", false); | |||
2302 | if (CGM.getTriple().isOSBinFormatCOFF()) { | |||
2303 | if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value)) { | |||
2304 | IdentifierInfo &II = CGF.CGM.getContext().Idents.get("NSAutoreleasePool"); | |||
2305 | TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); | |||
2306 | DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); | |||
2307 | ||||
2308 | const VarDecl *VD = nullptr; | |||
2309 | for (const auto &Result : DC->lookup(&II)) | |||
2310 | if ((VD = dyn_cast<VarDecl>(Result))) | |||
2311 | break; | |||
2312 | ||||
2313 | CGM.setGVProperties(ClassSymbol, VD); | |||
2314 | } | |||
2315 | } | |||
2316 | return Value; | |||
2317 | } | |||
2318 | ||||
2319 | llvm::Value *CGObjCGNU::GetTypedSelector(CodeGenFunction &CGF, Selector Sel, | |||
2320 | const std::string &TypeEncoding) { | |||
2321 | SmallVectorImpl<TypedSelector> &Types = SelectorTable[Sel]; | |||
2322 | llvm::GlobalAlias *SelValue = nullptr; | |||
2323 | ||||
2324 | for (SmallVectorImpl<TypedSelector>::iterator i = Types.begin(), | |||
2325 | e = Types.end() ; i!=e ; i++) { | |||
2326 | if (i->first == TypeEncoding) { | |||
2327 | SelValue = i->second; | |||
2328 | break; | |||
2329 | } | |||
2330 | } | |||
2331 | if (!SelValue) { | |||
2332 | SelValue = llvm::GlobalAlias::create( | |||
2333 | SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage, | |||
2334 | ".objc_selector_" + Sel.getAsString(), &TheModule); | |||
2335 | Types.emplace_back(TypeEncoding, SelValue); | |||
2336 | } | |||
2337 | ||||
2338 | return SelValue; | |||
2339 | } | |||
2340 | ||||
2341 | Address CGObjCGNU::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) { | |||
2342 | llvm::Value *SelValue = GetSelector(CGF, Sel); | |||
2343 | ||||
2344 | // Store it to a temporary. Does this satisfy the semantics of | |||
2345 | // GetAddrOfSelector? Hopefully. | |||
2346 | Address tmp = CGF.CreateTempAlloca(SelValue->getType(), | |||
2347 | CGF.getPointerAlign()); | |||
2348 | CGF.Builder.CreateStore(SelValue, tmp); | |||
2349 | return tmp; | |||
2350 | } | |||
2351 | ||||
2352 | llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel) { | |||
2353 | return GetTypedSelector(CGF, Sel, std::string()); | |||
2354 | } | |||
2355 | ||||
2356 | llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, | |||
2357 | const ObjCMethodDecl *Method) { | |||
2358 | std::string SelTypes = CGM.getContext().getObjCEncodingForMethodDecl(Method); | |||
2359 | return GetTypedSelector(CGF, Method->getSelector(), SelTypes); | |||
2360 | } | |||
2361 | ||||
2362 | llvm::Constant *CGObjCGNU::GetEHType(QualType T) { | |||
2363 | if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { | |||
2364 | // With the old ABI, there was only one kind of catchall, which broke | |||
2365 | // foreign exceptions. With the new ABI, we use __objc_id_typeinfo as | |||
2366 | // a pointer indicating object catchalls, and NULL to indicate real | |||
2367 | // catchalls | |||
2368 | if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { | |||
2369 | return MakeConstantString("@id"); | |||
2370 | } else { | |||
2371 | return nullptr; | |||
2372 | } | |||
2373 | } | |||
2374 | ||||
2375 | // All other types should be Objective-C interface pointer types. | |||
2376 | const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>(); | |||
2377 | assert(OPT && "Invalid @catch type.")((OPT && "Invalid @catch type.") ? static_cast<void > (0) : __assert_fail ("OPT && \"Invalid @catch type.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 2377, __PRETTY_FUNCTION__)); | |||
2378 | const ObjCInterfaceDecl *IDecl = OPT->getObjectType()->getInterface(); | |||
2379 | assert(IDecl && "Invalid @catch type.")((IDecl && "Invalid @catch type.") ? static_cast<void > (0) : __assert_fail ("IDecl && \"Invalid @catch type.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 2379, __PRETTY_FUNCTION__)); | |||
2380 | return MakeConstantString(IDecl->getIdentifier()->getName()); | |||
2381 | } | |||
2382 | ||||
2383 | llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) { | |||
2384 | if (usesSEHExceptions) | |||
2385 | return CGM.getCXXABI().getAddrOfRTTIDescriptor(T); | |||
2386 | ||||
2387 | if (!CGM.getLangOpts().CPlusPlus) | |||
2388 | return CGObjCGNU::GetEHType(T); | |||
2389 | ||||
2390 | // For Objective-C++, we want to provide the ability to catch both C++ and | |||
2391 | // Objective-C objects in the same function. | |||
2392 | ||||
2393 | // There's a particular fixed type info for 'id'. | |||
2394 | if (T->isObjCIdType() || | |||
2395 | T->isObjCQualifiedIdType()) { | |||
2396 | llvm::Constant *IDEHType = | |||
2397 | CGM.getModule().getGlobalVariable("__objc_id_type_info"); | |||
2398 | if (!IDEHType) | |||
2399 | IDEHType = | |||
2400 | new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty, | |||
2401 | false, | |||
2402 | llvm::GlobalValue::ExternalLinkage, | |||
2403 | nullptr, "__objc_id_type_info"); | |||
2404 | return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty); | |||
2405 | } | |||
2406 | ||||
2407 | const ObjCObjectPointerType *PT = | |||
2408 | T->getAs<ObjCObjectPointerType>(); | |||
2409 | assert(PT && "Invalid @catch type.")((PT && "Invalid @catch type.") ? static_cast<void > (0) : __assert_fail ("PT && \"Invalid @catch type.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 2409, __PRETTY_FUNCTION__)); | |||
2410 | const ObjCInterfaceType *IT = PT->getInterfaceType(); | |||
2411 | assert(IT && "Invalid @catch type.")((IT && "Invalid @catch type.") ? static_cast<void > (0) : __assert_fail ("IT && \"Invalid @catch type.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 2411, __PRETTY_FUNCTION__)); | |||
2412 | std::string className = IT->getDecl()->getIdentifier()->getName(); | |||
2413 | ||||
2414 | std::string typeinfoName = "__objc_eh_typeinfo_" + className; | |||
2415 | ||||
2416 | // Return the existing typeinfo if it exists | |||
2417 | llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName); | |||
2418 | if (typeinfo) | |||
2419 | return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty); | |||
2420 | ||||
2421 | // Otherwise create it. | |||
2422 | ||||
2423 | // vtable for gnustep::libobjc::__objc_class_type_info | |||
2424 | // It's quite ugly hard-coding this. Ideally we'd generate it using the host | |||
2425 | // platform's name mangling. | |||
2426 | const char *vtableName = "_ZTVN7gnustep7libobjc22__objc_class_type_infoE"; | |||
2427 | auto *Vtable = TheModule.getGlobalVariable(vtableName); | |||
2428 | if (!Vtable) { | |||
2429 | Vtable = new llvm::GlobalVariable(TheModule, PtrToInt8Ty, true, | |||
2430 | llvm::GlobalValue::ExternalLinkage, | |||
2431 | nullptr, vtableName); | |||
2432 | } | |||
2433 | llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2); | |||
2434 | auto *BVtable = llvm::ConstantExpr::getBitCast( | |||
2435 | llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two), | |||
2436 | PtrToInt8Ty); | |||
2437 | ||||
2438 | llvm::Constant *typeName = | |||
2439 | ExportUniqueString(className, "__objc_eh_typename_"); | |||
2440 | ||||
2441 | ConstantInitBuilder builder(CGM); | |||
2442 | auto fields = builder.beginStruct(); | |||
2443 | fields.add(BVtable); | |||
2444 | fields.add(typeName); | |||
2445 | llvm::Constant *TI = | |||
2446 | fields.finishAndCreateGlobal("__objc_eh_typeinfo_" + className, | |||
2447 | CGM.getPointerAlign(), | |||
2448 | /*constant*/ false, | |||
2449 | llvm::GlobalValue::LinkOnceODRLinkage); | |||
2450 | return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty); | |||
2451 | } | |||
2452 | ||||
2453 | /// Generate an NSConstantString object. | |||
2454 | ConstantAddress CGObjCGNU::GenerateConstantString(const StringLiteral *SL) { | |||
2455 | ||||
2456 | std::string Str = SL->getString().str(); | |||
2457 | CharUnits Align = CGM.getPointerAlign(); | |||
2458 | ||||
2459 | // Look for an existing one | |||
2460 | llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str); | |||
2461 | if (old != ObjCStrings.end()) | |||
2462 | return ConstantAddress(old->getValue(), Align); | |||
2463 | ||||
2464 | StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass; | |||
2465 | ||||
2466 | if (StringClass.empty()) StringClass = "NSConstantString"; | |||
2467 | ||||
2468 | std::string Sym = "_OBJC_CLASS_"; | |||
2469 | Sym += StringClass; | |||
2470 | ||||
2471 | llvm::Constant *isa = TheModule.getNamedGlobal(Sym); | |||
2472 | ||||
2473 | if (!isa) | |||
2474 | isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false, | |||
2475 | llvm::GlobalValue::ExternalWeakLinkage, nullptr, Sym); | |||
2476 | else if (isa->getType() != PtrToIdTy) | |||
2477 | isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy); | |||
2478 | ||||
2479 | ConstantInitBuilder Builder(CGM); | |||
2480 | auto Fields = Builder.beginStruct(); | |||
2481 | Fields.add(isa); | |||
2482 | Fields.add(MakeConstantString(Str)); | |||
2483 | Fields.addInt(IntTy, Str.size()); | |||
2484 | llvm::Constant *ObjCStr = | |||
2485 | Fields.finishAndCreateGlobal(".objc_str", Align); | |||
2486 | ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty); | |||
2487 | ObjCStrings[Str] = ObjCStr; | |||
2488 | ConstantStrings.push_back(ObjCStr); | |||
2489 | return ConstantAddress(ObjCStr, Align); | |||
2490 | } | |||
2491 | ||||
2492 | ///Generates a message send where the super is the receiver. This is a message | |||
2493 | ///send to self with special delivery semantics indicating which class's method | |||
2494 | ///should be called. | |||
2495 | RValue | |||
2496 | CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, | |||
2497 | ReturnValueSlot Return, | |||
2498 | QualType ResultType, | |||
2499 | Selector Sel, | |||
2500 | const ObjCInterfaceDecl *Class, | |||
2501 | bool isCategoryImpl, | |||
2502 | llvm::Value *Receiver, | |||
2503 | bool IsClassMessage, | |||
2504 | const CallArgList &CallArgs, | |||
2505 | const ObjCMethodDecl *Method) { | |||
2506 | CGBuilderTy &Builder = CGF.Builder; | |||
2507 | if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { | |||
2508 | if (Sel == RetainSel || Sel == AutoreleaseSel) { | |||
2509 | return RValue::get(EnforceType(Builder, Receiver, | |||
2510 | CGM.getTypes().ConvertType(ResultType))); | |||
2511 | } | |||
2512 | if (Sel == ReleaseSel) { | |||
2513 | return RValue::get(nullptr); | |||
2514 | } | |||
2515 | } | |||
2516 | ||||
2517 | llvm::Value *cmd = GetSelector(CGF, Sel); | |||
2518 | CallArgList ActualArgs; | |||
2519 | ||||
2520 | ActualArgs.add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy); | |||
2521 | ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType()); | |||
2522 | ActualArgs.addFrom(CallArgs); | |||
2523 | ||||
2524 | MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); | |||
2525 | ||||
2526 | llvm::Value *ReceiverClass = nullptr; | |||
2527 | bool isV2ABI = isRuntime(ObjCRuntime::GNUstep, 2); | |||
2528 | if (isV2ABI) { | |||
2529 | ReceiverClass = GetClassNamed(CGF, | |||
2530 | Class->getSuperClass()->getNameAsString(), /*isWeak*/false); | |||
2531 | if (IsClassMessage) { | |||
2532 | // Load the isa pointer of the superclass is this is a class method. | |||
2533 | ReceiverClass = Builder.CreateBitCast(ReceiverClass, | |||
2534 | llvm::PointerType::getUnqual(IdTy)); | |||
2535 | ReceiverClass = | |||
2536 | Builder.CreateAlignedLoad(ReceiverClass, CGF.getPointerAlign()); | |||
2537 | } | |||
2538 | ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy); | |||
2539 | } else { | |||
2540 | if (isCategoryImpl) { | |||
2541 | llvm::FunctionCallee classLookupFunction = nullptr; | |||
2542 | if (IsClassMessage) { | |||
2543 | classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( | |||
2544 | IdTy, PtrTy, true), "objc_get_meta_class"); | |||
2545 | } else { | |||
2546 | classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( | |||
2547 | IdTy, PtrTy, true), "objc_get_class"); | |||
2548 | } | |||
2549 | ReceiverClass = Builder.CreateCall(classLookupFunction, | |||
2550 | MakeConstantString(Class->getNameAsString())); | |||
2551 | } else { | |||
2552 | // Set up global aliases for the metaclass or class pointer if they do not | |||
2553 | // already exist. These will are forward-references which will be set to | |||
2554 | // pointers to the class and metaclass structure created for the runtime | |||
2555 | // load function. To send a message to super, we look up the value of the | |||
2556 | // super_class pointer from either the class or metaclass structure. | |||
2557 | if (IsClassMessage) { | |||
2558 | if (!MetaClassPtrAlias) { | |||
2559 | MetaClassPtrAlias = llvm::GlobalAlias::create( | |||
2560 | IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage, | |||
2561 | ".objc_metaclass_ref" + Class->getNameAsString(), &TheModule); | |||
2562 | } | |||
2563 | ReceiverClass = MetaClassPtrAlias; | |||
2564 | } else { | |||
2565 | if (!ClassPtrAlias) { | |||
2566 | ClassPtrAlias = llvm::GlobalAlias::create( | |||
2567 | IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage, | |||
2568 | ".objc_class_ref" + Class->getNameAsString(), &TheModule); | |||
2569 | } | |||
2570 | ReceiverClass = ClassPtrAlias; | |||
2571 | } | |||
2572 | } | |||
2573 | // Cast the pointer to a simplified version of the class structure | |||
2574 | llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy); | |||
2575 | ReceiverClass = Builder.CreateBitCast(ReceiverClass, | |||
2576 | llvm::PointerType::getUnqual(CastTy)); | |||
2577 | // Get the superclass pointer | |||
2578 | ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1); | |||
2579 | // Load the superclass pointer | |||
2580 | ReceiverClass = | |||
2581 | Builder.CreateAlignedLoad(ReceiverClass, CGF.getPointerAlign()); | |||
2582 | } | |||
2583 | // Construct the structure used to look up the IMP | |||
2584 | llvm::StructType *ObjCSuperTy = | |||
2585 | llvm::StructType::get(Receiver->getType(), IdTy); | |||
2586 | ||||
2587 | Address ObjCSuper = CGF.CreateTempAlloca(ObjCSuperTy, | |||
2588 | CGF.getPointerAlign()); | |||
2589 | ||||
2590 | Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0)); | |||
2591 | Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1)); | |||
2592 | ||||
2593 | ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy); | |||
2594 | ||||
2595 | // Get the IMP | |||
2596 | llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI); | |||
2597 | imp = EnforceType(Builder, imp, MSI.MessengerType); | |||
2598 | ||||
2599 | llvm::Metadata *impMD[] = { | |||
2600 | llvm::MDString::get(VMContext, Sel.getAsString()), | |||
2601 | llvm::MDString::get(VMContext, Class->getSuperClass()->getNameAsString()), | |||
2602 | llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( | |||
2603 | llvm::Type::getInt1Ty(VMContext), IsClassMessage))}; | |||
2604 | llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD); | |||
2605 | ||||
2606 | CGCallee callee(CGCalleeInfo(), imp); | |||
2607 | ||||
2608 | llvm::CallBase *call; | |||
2609 | RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); | |||
2610 | call->setMetadata(msgSendMDKind, node); | |||
2611 | return msgRet; | |||
2612 | } | |||
2613 | ||||
2614 | /// Generate code for a message send expression. | |||
2615 | RValue | |||
2616 | CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, | |||
2617 | ReturnValueSlot Return, | |||
2618 | QualType ResultType, | |||
2619 | Selector Sel, | |||
2620 | llvm::Value *Receiver, | |||
2621 | const CallArgList &CallArgs, | |||
2622 | const ObjCInterfaceDecl *Class, | |||
2623 | const ObjCMethodDecl *Method) { | |||
2624 | CGBuilderTy &Builder = CGF.Builder; | |||
2625 | ||||
2626 | // Strip out message sends to retain / release in GC mode | |||
2627 | if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { | |||
2628 | if (Sel == RetainSel || Sel == AutoreleaseSel) { | |||
2629 | return RValue::get(EnforceType(Builder, Receiver, | |||
2630 | CGM.getTypes().ConvertType(ResultType))); | |||
2631 | } | |||
2632 | if (Sel == ReleaseSel) { | |||
2633 | return RValue::get(nullptr); | |||
2634 | } | |||
2635 | } | |||
2636 | ||||
2637 | // If the return type is something that goes in an integer register, the | |||
2638 | // runtime will handle 0 returns. For other cases, we fill in the 0 value | |||
2639 | // ourselves. | |||
2640 | // | |||
2641 | // The language spec says the result of this kind of message send is | |||
2642 | // undefined, but lots of people seem to have forgotten to read that | |||
2643 | // paragraph and insist on sending messages to nil that have structure | |||
2644 | // returns. With GCC, this generates a random return value (whatever happens | |||
2645 | // to be on the stack / in those registers at the time) on most platforms, | |||
2646 | // and generates an illegal instruction trap on SPARC. With LLVM it corrupts | |||
2647 | // the stack. | |||
2648 | bool isPointerSizedReturn = (ResultType->isAnyPointerType() || | |||
2649 | ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType()); | |||
2650 | ||||
2651 | llvm::BasicBlock *startBB = nullptr; | |||
2652 | llvm::BasicBlock *messageBB = nullptr; | |||
2653 | llvm::BasicBlock *continueBB = nullptr; | |||
2654 | ||||
2655 | if (!isPointerSizedReturn) { | |||
2656 | startBB = Builder.GetInsertBlock(); | |||
2657 | messageBB = CGF.createBasicBlock("msgSend"); | |||
2658 | continueBB = CGF.createBasicBlock("continue"); | |||
2659 | ||||
2660 | llvm::Value *isNil = Builder.CreateICmpEQ(Receiver, | |||
2661 | llvm::Constant::getNullValue(Receiver->getType())); | |||
2662 | Builder.CreateCondBr(isNil, continueBB, messageBB); | |||
2663 | CGF.EmitBlock(messageBB); | |||
2664 | } | |||
2665 | ||||
2666 | IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); | |||
2667 | llvm::Value *cmd; | |||
2668 | if (Method) | |||
2669 | cmd = GetSelector(CGF, Method); | |||
2670 | else | |||
2671 | cmd = GetSelector(CGF, Sel); | |||
2672 | cmd = EnforceType(Builder, cmd, SelectorTy); | |||
2673 | Receiver = EnforceType(Builder, Receiver, IdTy); | |||
2674 | ||||
2675 | llvm::Metadata *impMD[] = { | |||
2676 | llvm::MDString::get(VMContext, Sel.getAsString()), | |||
2677 | llvm::MDString::get(VMContext, Class ? Class->getNameAsString() : ""), | |||
2678 | llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( | |||
2679 | llvm::Type::getInt1Ty(VMContext), Class != nullptr))}; | |||
2680 | llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD); | |||
2681 | ||||
2682 | CallArgList ActualArgs; | |||
2683 | ActualArgs.add(RValue::get(Receiver), ASTIdTy); | |||
2684 | ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType()); | |||
2685 | ActualArgs.addFrom(CallArgs); | |||
2686 | ||||
2687 | MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); | |||
2688 | ||||
2689 | // Get the IMP to call | |||
2690 | llvm::Value *imp; | |||
2691 | ||||
2692 | // If we have non-legacy dispatch specified, we try using the objc_msgSend() | |||
2693 | // functions. These are not supported on all platforms (or all runtimes on a | |||
2694 | // given platform), so we | |||
2695 | switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { | |||
2696 | case CodeGenOptions::Legacy: | |||
2697 | imp = LookupIMP(CGF, Receiver, cmd, node, MSI); | |||
2698 | break; | |||
2699 | case CodeGenOptions::Mixed: | |||
2700 | case CodeGenOptions::NonLegacy: | |||
2701 | if (CGM.ReturnTypeUsesFPRet(ResultType)) { | |||
2702 | imp = | |||
2703 | CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), | |||
2704 | "objc_msgSend_fpret") | |||
2705 | .getCallee(); | |||
2706 | } else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { | |||
2707 | // The actual types here don't matter - we're going to bitcast the | |||
2708 | // function anyway | |||
2709 | imp = | |||
2710 | CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), | |||
2711 | "objc_msgSend_stret") | |||
2712 | .getCallee(); | |||
2713 | } else { | |||
2714 | imp = CGM.CreateRuntimeFunction( | |||
2715 | llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend") | |||
2716 | .getCallee(); | |||
2717 | } | |||
2718 | } | |||
2719 | ||||
2720 | // Reset the receiver in case the lookup modified it | |||
2721 | ActualArgs[0] = CallArg(RValue::get(Receiver), ASTIdTy); | |||
2722 | ||||
2723 | imp = EnforceType(Builder, imp, MSI.MessengerType); | |||
2724 | ||||
2725 | llvm::CallBase *call; | |||
2726 | CGCallee callee(CGCalleeInfo(), imp); | |||
2727 | RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); | |||
2728 | call->setMetadata(msgSendMDKind, node); | |||
2729 | ||||
2730 | ||||
2731 | if (!isPointerSizedReturn) { | |||
2732 | messageBB = CGF.Builder.GetInsertBlock(); | |||
2733 | CGF.Builder.CreateBr(continueBB); | |||
2734 | CGF.EmitBlock(continueBB); | |||
2735 | if (msgRet.isScalar()) { | |||
2736 | llvm::Value *v = msgRet.getScalarVal(); | |||
2737 | llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2); | |||
2738 | phi->addIncoming(v, messageBB); | |||
2739 | phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB); | |||
2740 | msgRet = RValue::get(phi); | |||
2741 | } else if (msgRet.isAggregate()) { | |||
2742 | Address v = msgRet.getAggregateAddress(); | |||
2743 | llvm::PHINode *phi = Builder.CreatePHI(v.getType(), 2); | |||
2744 | llvm::Type *RetTy = v.getElementType(); | |||
2745 | Address NullVal = CGF.CreateTempAlloca(RetTy, v.getAlignment(), "null"); | |||
2746 | CGF.InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy)); | |||
2747 | phi->addIncoming(v.getPointer(), messageBB); | |||
2748 | phi->addIncoming(NullVal.getPointer(), startBB); | |||
2749 | msgRet = RValue::getAggregate(Address(phi, v.getAlignment())); | |||
2750 | } else /* isComplex() */ { | |||
2751 | std::pair<llvm::Value*,llvm::Value*> v = msgRet.getComplexVal(); | |||
2752 | llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2); | |||
2753 | phi->addIncoming(v.first, messageBB); | |||
2754 | phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()), | |||
2755 | startBB); | |||
2756 | llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2); | |||
2757 | phi2->addIncoming(v.second, messageBB); | |||
2758 | phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()), | |||
2759 | startBB); | |||
2760 | msgRet = RValue::getComplex(phi, phi2); | |||
2761 | } | |||
2762 | } | |||
2763 | return msgRet; | |||
2764 | } | |||
2765 | ||||
2766 | /// Generates a MethodList. Used in construction of a objc_class and | |||
2767 | /// objc_category structures. | |||
2768 | llvm::Constant *CGObjCGNU:: | |||
2769 | GenerateMethodList(StringRef ClassName, | |||
2770 | StringRef CategoryName, | |||
2771 | ArrayRef<const ObjCMethodDecl*> Methods, | |||
2772 | bool isClassMethodList) { | |||
2773 | if (Methods.empty()) | |||
2774 | return NULLPtr; | |||
2775 | ||||
2776 | ConstantInitBuilder Builder(CGM); | |||
2777 | ||||
2778 | auto MethodList = Builder.beginStruct(); | |||
2779 | MethodList.addNullPointer(CGM.Int8PtrTy); | |||
2780 | MethodList.addInt(Int32Ty, Methods.size()); | |||
2781 | ||||
2782 | // Get the method structure type. | |||
2783 | llvm::StructType *ObjCMethodTy = | |||
2784 | llvm::StructType::get(CGM.getLLVMContext(), { | |||
2785 | PtrToInt8Ty, // Really a selector, but the runtime creates it us. | |||
2786 | PtrToInt8Ty, // Method types | |||
2787 | IMPTy // Method pointer | |||
2788 | }); | |||
2789 | bool isV2ABI = isRuntime(ObjCRuntime::GNUstep, 2); | |||
2790 | if (isV2ABI) { | |||
2791 | // size_t size; | |||
2792 | llvm::DataLayout td(&TheModule); | |||
2793 | MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) / | |||
2794 | CGM.getContext().getCharWidth()); | |||
2795 | ObjCMethodTy = | |||
2796 | llvm::StructType::get(CGM.getLLVMContext(), { | |||
2797 | IMPTy, // Method pointer | |||
2798 | PtrToInt8Ty, // Selector | |||
2799 | PtrToInt8Ty // Extended type encoding | |||
2800 | }); | |||
2801 | } else { | |||
2802 | ObjCMethodTy = | |||
2803 | llvm::StructType::get(CGM.getLLVMContext(), { | |||
2804 | PtrToInt8Ty, // Really a selector, but the runtime creates it us. | |||
2805 | PtrToInt8Ty, // Method types | |||
2806 | IMPTy // Method pointer | |||
2807 | }); | |||
2808 | } | |||
2809 | auto MethodArray = MethodList.beginArray(); | |||
2810 | ASTContext &Context = CGM.getContext(); | |||
2811 | for (const auto *OMD : Methods) { | |||
2812 | llvm::Constant *FnPtr = | |||
2813 | TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName, | |||
2814 | OMD->getSelector(), | |||
2815 | isClassMethodList)); | |||
2816 | assert(FnPtr && "Can't generate metadata for method that doesn't exist")((FnPtr && "Can't generate metadata for method that doesn't exist" ) ? static_cast<void> (0) : __assert_fail ("FnPtr && \"Can't generate metadata for method that doesn't exist\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 2816, __PRETTY_FUNCTION__)); | |||
2817 | auto Method = MethodArray.beginStruct(ObjCMethodTy); | |||
2818 | if (isV2ABI) { | |||
2819 | Method.addBitCast(FnPtr, IMPTy); | |||
2820 | Method.add(GetConstantSelector(OMD->getSelector(), | |||
2821 | Context.getObjCEncodingForMethodDecl(OMD))); | |||
2822 | Method.add(MakeConstantString(Context.getObjCEncodingForMethodDecl(OMD, true))); | |||
2823 | } else { | |||
2824 | Method.add(MakeConstantString(OMD->getSelector().getAsString())); | |||
2825 | Method.add(MakeConstantString(Context.getObjCEncodingForMethodDecl(OMD))); | |||
2826 | Method.addBitCast(FnPtr, IMPTy); | |||
2827 | } | |||
2828 | Method.finishAndAddTo(MethodArray); | |||
2829 | } | |||
2830 | MethodArray.finishAndAddTo(MethodList); | |||
2831 | ||||
2832 | // Create an instance of the structure | |||
2833 | return MethodList.finishAndCreateGlobal(".objc_method_list", | |||
2834 | CGM.getPointerAlign()); | |||
2835 | } | |||
2836 | ||||
2837 | /// Generates an IvarList. Used in construction of a objc_class. | |||
2838 | llvm::Constant *CGObjCGNU:: | |||
2839 | GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames, | |||
2840 | ArrayRef<llvm::Constant *> IvarTypes, | |||
2841 | ArrayRef<llvm::Constant *> IvarOffsets, | |||
2842 | ArrayRef<llvm::Constant *> IvarAlign, | |||
2843 | ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership) { | |||
2844 | if (IvarNames.empty()) | |||
2845 | return NULLPtr; | |||
2846 | ||||
2847 | ConstantInitBuilder Builder(CGM); | |||
2848 | ||||
2849 | // Structure containing array count followed by array. | |||
2850 | auto IvarList = Builder.beginStruct(); | |||
2851 | IvarList.addInt(IntTy, (int)IvarNames.size()); | |||
2852 | ||||
2853 | // Get the ivar structure type. | |||
2854 | llvm::StructType *ObjCIvarTy = | |||
2855 | llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy); | |||
2856 | ||||
2857 | // Array of ivar structures. | |||
2858 | auto Ivars = IvarList.beginArray(ObjCIvarTy); | |||
2859 | for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) { | |||
2860 | auto Ivar = Ivars.beginStruct(ObjCIvarTy); | |||
2861 | Ivar.add(IvarNames[i]); | |||
2862 | Ivar.add(IvarTypes[i]); | |||
2863 | Ivar.add(IvarOffsets[i]); | |||
2864 | Ivar.finishAndAddTo(Ivars); | |||
2865 | } | |||
2866 | Ivars.finishAndAddTo(IvarList); | |||
2867 | ||||
2868 | // Create an instance of the structure | |||
2869 | return IvarList.finishAndCreateGlobal(".objc_ivar_list", | |||
2870 | CGM.getPointerAlign()); | |||
2871 | } | |||
2872 | ||||
2873 | /// Generate a class structure | |||
2874 | llvm::Constant *CGObjCGNU::GenerateClassStructure( | |||
2875 | llvm::Constant *MetaClass, | |||
2876 | llvm::Constant *SuperClass, | |||
2877 | unsigned info, | |||
2878 | const char *Name, | |||
2879 | llvm::Constant *Version, | |||
2880 | llvm::Constant *InstanceSize, | |||
2881 | llvm::Constant *IVars, | |||
2882 | llvm::Constant *Methods, | |||
2883 | llvm::Constant *Protocols, | |||
2884 | llvm::Constant *IvarOffsets, | |||
2885 | llvm::Constant *Properties, | |||
2886 | llvm::Constant *StrongIvarBitmap, | |||
2887 | llvm::Constant *WeakIvarBitmap, | |||
2888 | bool isMeta) { | |||
2889 | // Set up the class structure | |||
2890 | // Note: Several of these are char*s when they should be ids. This is | |||
2891 | // because the runtime performs this translation on load. | |||
2892 | // | |||
2893 | // Fields marked New ABI are part of the GNUstep runtime. We emit them | |||
2894 | // anyway; the classes will still work with the GNU runtime, they will just | |||
2895 | // be ignored. | |||
2896 | llvm::StructType *ClassTy = llvm::StructType::get( | |||
2897 | PtrToInt8Ty, // isa | |||
2898 | PtrToInt8Ty, // super_class | |||
2899 | PtrToInt8Ty, // name | |||
2900 | LongTy, // version | |||
2901 | LongTy, // info | |||
2902 | LongTy, // instance_size | |||
2903 | IVars->getType(), // ivars | |||
2904 | Methods->getType(), // methods | |||
2905 | // These are all filled in by the runtime, so we pretend | |||
2906 | PtrTy, // dtable | |||
2907 | PtrTy, // subclass_list | |||
2908 | PtrTy, // sibling_class | |||
2909 | PtrTy, // protocols | |||
2910 | PtrTy, // gc_object_type | |||
2911 | // New ABI: | |||
2912 | LongTy, // abi_version | |||
2913 | IvarOffsets->getType(), // ivar_offsets | |||
2914 | Properties->getType(), // properties | |||
2915 | IntPtrTy, // strong_pointers | |||
2916 | IntPtrTy // weak_pointers | |||
2917 | ); | |||
2918 | ||||
2919 | ConstantInitBuilder Builder(CGM); | |||
2920 | auto Elements = Builder.beginStruct(ClassTy); | |||
2921 | ||||
2922 | // Fill in the structure | |||
2923 | ||||
2924 | // isa | |||
2925 | Elements.addBitCast(MetaClass, PtrToInt8Ty); | |||
2926 | // super_class | |||
2927 | Elements.add(SuperClass); | |||
2928 | // name | |||
2929 | Elements.add(MakeConstantString(Name, ".class_name")); | |||
2930 | // version | |||
2931 | Elements.addInt(LongTy, 0); | |||
2932 | // info | |||
2933 | Elements.addInt(LongTy, info); | |||
2934 | // instance_size | |||
2935 | if (isMeta) { | |||
2936 | llvm::DataLayout td(&TheModule); | |||
2937 | Elements.addInt(LongTy, | |||
2938 | td.getTypeSizeInBits(ClassTy) / | |||
2939 | CGM.getContext().getCharWidth()); | |||
2940 | } else | |||
2941 | Elements.add(InstanceSize); | |||
2942 | // ivars | |||
2943 | Elements.add(IVars); | |||
2944 | // methods | |||
2945 | Elements.add(Methods); | |||
2946 | // These are all filled in by the runtime, so we pretend | |||
2947 | // dtable | |||
2948 | Elements.add(NULLPtr); | |||
2949 | // subclass_list | |||
2950 | Elements.add(NULLPtr); | |||
2951 | // sibling_class | |||
2952 | Elements.add(NULLPtr); | |||
2953 | // protocols | |||
2954 | Elements.addBitCast(Protocols, PtrTy); | |||
2955 | // gc_object_type | |||
2956 | Elements.add(NULLPtr); | |||
2957 | // abi_version | |||
2958 | Elements.addInt(LongTy, ClassABIVersion); | |||
2959 | // ivar_offsets | |||
2960 | Elements.add(IvarOffsets); | |||
2961 | // properties | |||
2962 | Elements.add(Properties); | |||
2963 | // strong_pointers | |||
2964 | Elements.add(StrongIvarBitmap); | |||
2965 | // weak_pointers | |||
2966 | Elements.add(WeakIvarBitmap); | |||
2967 | // Create an instance of the structure | |||
2968 | // This is now an externally visible symbol, so that we can speed up class | |||
2969 | // messages in the next ABI. We may already have some weak references to | |||
2970 | // this, so check and fix them properly. | |||
2971 | std::string ClassSym((isMeta ? "_OBJC_METACLASS_": "_OBJC_CLASS_") + | |||
2972 | std::string(Name)); | |||
2973 | llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym); | |||
2974 | llvm::Constant *Class = | |||
2975 | Elements.finishAndCreateGlobal(ClassSym, CGM.getPointerAlign(), false, | |||
2976 | llvm::GlobalValue::ExternalLinkage); | |||
2977 | if (ClassRef) { | |||
2978 | ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class, | |||
2979 | ClassRef->getType())); | |||
2980 | ClassRef->removeFromParent(); | |||
2981 | Class->setName(ClassSym); | |||
2982 | } | |||
2983 | return Class; | |||
2984 | } | |||
2985 | ||||
2986 | llvm::Constant *CGObjCGNU:: | |||
2987 | GenerateProtocolMethodList(ArrayRef<const ObjCMethodDecl*> Methods) { | |||
2988 | // Get the method structure type. | |||
2989 | llvm::StructType *ObjCMethodDescTy = | |||
2990 | llvm::StructType::get(CGM.getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty }); | |||
2991 | ASTContext &Context = CGM.getContext(); | |||
2992 | ConstantInitBuilder Builder(CGM); | |||
2993 | auto MethodList = Builder.beginStruct(); | |||
2994 | MethodList.addInt(IntTy, Methods.size()); | |||
2995 | auto MethodArray = MethodList.beginArray(ObjCMethodDescTy); | |||
2996 | for (auto *M : Methods) { | |||
2997 | auto Method = MethodArray.beginStruct(ObjCMethodDescTy); | |||
2998 | Method.add(MakeConstantString(M->getSelector().getAsString())); | |||
2999 | Method.add(MakeConstantString(Context.getObjCEncodingForMethodDecl(M))); | |||
3000 | Method.finishAndAddTo(MethodArray); | |||
3001 | } | |||
3002 | MethodArray.finishAndAddTo(MethodList); | |||
3003 | return MethodList.finishAndCreateGlobal(".objc_method_list", | |||
3004 | CGM.getPointerAlign()); | |||
3005 | } | |||
3006 | ||||
3007 | // Create the protocol list structure used in classes, categories and so on | |||
3008 | llvm::Constant * | |||
3009 | CGObjCGNU::GenerateProtocolList(ArrayRef<std::string> Protocols) { | |||
3010 | ||||
3011 | ConstantInitBuilder Builder(CGM); | |||
3012 | auto ProtocolList = Builder.beginStruct(); | |||
3013 | ProtocolList.add(NULLPtr); | |||
3014 | ProtocolList.addInt(LongTy, Protocols.size()); | |||
3015 | ||||
3016 | auto Elements = ProtocolList.beginArray(PtrToInt8Ty); | |||
3017 | for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); | |||
3018 | iter != endIter ; iter++) { | |||
3019 | llvm::Constant *protocol = nullptr; | |||
3020 | llvm::StringMap<llvm::Constant*>::iterator value = | |||
3021 | ExistingProtocols.find(*iter); | |||
3022 | if (value == ExistingProtocols.end()) { | |||
3023 | protocol = GenerateEmptyProtocol(*iter); | |||
3024 | } else { | |||
3025 | protocol = value->getValue(); | |||
3026 | } | |||
3027 | Elements.addBitCast(protocol, PtrToInt8Ty); | |||
3028 | } | |||
3029 | Elements.finishAndAddTo(ProtocolList); | |||
3030 | return ProtocolList.finishAndCreateGlobal(".objc_protocol_list", | |||
3031 | CGM.getPointerAlign()); | |||
3032 | } | |||
3033 | ||||
3034 | llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF, | |||
3035 | const ObjCProtocolDecl *PD) { | |||
3036 | llvm::Constant *&protocol = ExistingProtocols[PD->getNameAsString()]; | |||
| ||||
3037 | if (!protocol) | |||
3038 | GenerateProtocol(PD); | |||
3039 | llvm::Type *T = | |||
3040 | CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); | |||
3041 | return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); | |||
3042 | } | |||
3043 | ||||
3044 | llvm::Constant * | |||
3045 | CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) { | |||
3046 | llvm::Constant *ProtocolList = GenerateProtocolList({}); | |||
3047 | llvm::Constant *MethodList = GenerateProtocolMethodList({}); | |||
3048 | MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty); | |||
3049 | // Protocols are objects containing lists of the methods implemented and | |||
3050 | // protocols adopted. | |||
3051 | ConstantInitBuilder Builder(CGM); | |||
3052 | auto Elements = Builder.beginStruct(); | |||
3053 | ||||
3054 | // The isa pointer must be set to a magic number so the runtime knows it's | |||
3055 | // the correct layout. | |||
3056 | Elements.add(llvm::ConstantExpr::getIntToPtr( | |||
3057 | llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy)); | |||
3058 | ||||
3059 | Elements.add(MakeConstantString(ProtocolName, ".objc_protocol_name")); | |||
3060 | Elements.add(ProtocolList); /* .protocol_list */ | |||
3061 | Elements.add(MethodList); /* .instance_methods */ | |||
3062 | Elements.add(MethodList); /* .class_methods */ | |||
3063 | Elements.add(MethodList); /* .optional_instance_methods */ | |||
3064 | Elements.add(MethodList); /* .optional_class_methods */ | |||
3065 | Elements.add(NULLPtr); /* .properties */ | |||
3066 | Elements.add(NULLPtr); /* .optional_properties */ | |||
3067 | return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName), | |||
3068 | CGM.getPointerAlign()); | |||
3069 | } | |||
3070 | ||||
3071 | void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { | |||
3072 | std::string ProtocolName = PD->getNameAsString(); | |||
3073 | ||||
3074 | // Use the protocol definition, if there is one. | |||
3075 | if (const ObjCProtocolDecl *Def = PD->getDefinition()) | |||
3076 | PD = Def; | |||
3077 | ||||
3078 | SmallVector<std::string, 16> Protocols; | |||
3079 | for (const auto *PI : PD->protocols()) | |||
3080 | Protocols.push_back(PI->getNameAsString()); | |||
3081 | SmallVector<const ObjCMethodDecl*, 16> InstanceMethods; | |||
3082 | SmallVector<const ObjCMethodDecl*, 16> OptionalInstanceMethods; | |||
3083 | for (const auto *I : PD->instance_methods()) | |||
3084 | if (I->isOptional()) | |||
3085 | OptionalInstanceMethods.push_back(I); | |||
3086 | else | |||
3087 | InstanceMethods.push_back(I); | |||
3088 | // Collect information about class methods: | |||
3089 | SmallVector<const ObjCMethodDecl*, 16> ClassMethods; | |||
3090 | SmallVector<const ObjCMethodDecl*, 16> OptionalClassMethods; | |||
3091 | for (const auto *I : PD->class_methods()) | |||
3092 | if (I->isOptional()) | |||
3093 | OptionalClassMethods.push_back(I); | |||
3094 | else | |||
3095 | ClassMethods.push_back(I); | |||
3096 | ||||
3097 | llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); | |||
3098 | llvm::Constant *InstanceMethodList = | |||
3099 | GenerateProtocolMethodList(InstanceMethods); | |||
3100 | llvm::Constant *ClassMethodList = | |||
3101 | GenerateProtocolMethodList(ClassMethods); | |||
3102 | llvm::Constant *OptionalInstanceMethodList = | |||
3103 | GenerateProtocolMethodList(OptionalInstanceMethods); | |||
3104 | llvm::Constant *OptionalClassMethodList = | |||
3105 | GenerateProtocolMethodList(OptionalClassMethods); | |||
3106 | ||||
3107 | // Property metadata: name, attributes, isSynthesized, setter name, setter | |||
3108 | // types, getter name, getter types. | |||
3109 | // The isSynthesized value is always set to 0 in a protocol. It exists to | |||
3110 | // simplify the runtime library by allowing it to use the same data | |||
3111 | // structures for protocol metadata everywhere. | |||
3112 | ||||
3113 | llvm::Constant *PropertyList = | |||
3114 | GeneratePropertyList(nullptr, PD, false, false); | |||
3115 | llvm::Constant *OptionalPropertyList = | |||
3116 | GeneratePropertyList(nullptr, PD, false, true); | |||
3117 | ||||
3118 | // Protocols are objects containing lists of the methods implemented and | |||
3119 | // protocols adopted. | |||
3120 | // The isa pointer must be set to a magic number so the runtime knows it's | |||
3121 | // the correct layout. | |||
3122 | ConstantInitBuilder Builder(CGM); | |||
3123 | auto Elements = Builder.beginStruct(); | |||
3124 | Elements.add( | |||
3125 | llvm::ConstantExpr::getIntToPtr( | |||
3126 | llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy)); | |||
3127 | Elements.add(MakeConstantString(ProtocolName)); | |||
3128 | Elements.add(ProtocolList); | |||
3129 | Elements.add(InstanceMethodList); | |||
3130 | Elements.add(ClassMethodList); | |||
3131 | Elements.add(OptionalInstanceMethodList); | |||
3132 | Elements.add(OptionalClassMethodList); | |||
3133 | Elements.add(PropertyList); | |||
3134 | Elements.add(OptionalPropertyList); | |||
3135 | ExistingProtocols[ProtocolName] = | |||
3136 | llvm::ConstantExpr::getBitCast( | |||
3137 | Elements.finishAndCreateGlobal(".objc_protocol", CGM.getPointerAlign()), | |||
3138 | IdTy); | |||
3139 | } | |||
3140 | void CGObjCGNU::GenerateProtocolHolderCategory() { | |||
3141 | // Collect information about instance methods | |||
3142 | ||||
3143 | ConstantInitBuilder Builder(CGM); | |||
3144 | auto Elements = Builder.beginStruct(); | |||
3145 | ||||
3146 | const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack"; | |||
3147 | const std::string CategoryName = "AnotherHack"; | |||
3148 | Elements.add(MakeConstantString(CategoryName)); | |||
3149 | Elements.add(MakeConstantString(ClassName)); | |||
3150 | // Instance method list | |||
3151 | Elements.addBitCast(GenerateMethodList( | |||
3152 | ClassName, CategoryName, {}, false), PtrTy); | |||
3153 | // Class method list | |||
3154 | Elements.addBitCast(GenerateMethodList( | |||
3155 | ClassName, CategoryName, {}, true), PtrTy); | |||
3156 | ||||
3157 | // Protocol list | |||
3158 | ConstantInitBuilder ProtocolListBuilder(CGM); | |||
3159 | auto ProtocolList = ProtocolListBuilder.beginStruct(); | |||
3160 | ProtocolList.add(NULLPtr); | |||
3161 | ProtocolList.addInt(LongTy, ExistingProtocols.size()); | |||
3162 | auto ProtocolElements = ProtocolList.beginArray(PtrTy); | |||
3163 | for (auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end(); | |||
3164 | iter != endIter ; iter++) { | |||
3165 | ProtocolElements.addBitCast(iter->getValue(), PtrTy); | |||
3166 | } | |||
3167 | ProtocolElements.finishAndAddTo(ProtocolList); | |||
3168 | Elements.addBitCast( | |||
3169 | ProtocolList.finishAndCreateGlobal(".objc_protocol_list", | |||
3170 | CGM.getPointerAlign()), | |||
3171 | PtrTy); | |||
3172 | Categories.push_back(llvm::ConstantExpr::getBitCast( | |||
3173 | Elements.finishAndCreateGlobal("", CGM.getPointerAlign()), | |||
3174 | PtrTy)); | |||
3175 | } | |||
3176 | ||||
3177 | /// Libobjc2 uses a bitfield representation where small(ish) bitfields are | |||
3178 | /// stored in a 64-bit value with the low bit set to 1 and the remaining 63 | |||
3179 | /// bits set to their values, LSB first, while larger ones are stored in a | |||
3180 | /// structure of this / form: | |||
3181 | /// | |||
3182 | /// struct { int32_t length; int32_t values[length]; }; | |||
3183 | /// | |||
3184 | /// The values in the array are stored in host-endian format, with the least | |||
3185 | /// significant bit being assumed to come first in the bitfield. Therefore, a | |||
3186 | /// bitfield with the 64th bit set will be (int64_t)&{ 2, [0, 1<<31] }, while a | |||
3187 | /// bitfield / with the 63rd bit set will be 1<<64. | |||
3188 | llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) { | |||
3189 | int bitCount = bits.size(); | |||
3190 | int ptrBits = CGM.getDataLayout().getPointerSizeInBits(); | |||
3191 | if (bitCount < ptrBits) { | |||
3192 | uint64_t val = 1; | |||
3193 | for (int i=0 ; i<bitCount ; ++i) { | |||
3194 | if (bits[i]) val |= 1ULL<<(i+1); | |||
3195 | } | |||
3196 | return llvm::ConstantInt::get(IntPtrTy, val); | |||
3197 | } | |||
3198 | SmallVector<llvm::Constant *, 8> values; | |||
3199 | int v=0; | |||
3200 | while (v < bitCount) { | |||
3201 | int32_t word = 0; | |||
3202 | for (int i=0 ; (i<32) && (v<bitCount) ; ++i) { | |||
3203 | if (bits[v]) word |= 1<<i; | |||
3204 | v++; | |||
3205 | } | |||
3206 | values.push_back(llvm::ConstantInt::get(Int32Ty, word)); | |||
3207 | } | |||
3208 | ||||
3209 | ConstantInitBuilder builder(CGM); | |||
3210 | auto fields = builder.beginStruct(); | |||
3211 | fields.addInt(Int32Ty, values.size()); | |||
3212 | auto array = fields.beginArray(); | |||
3213 | for (auto v : values) array.add(v); | |||
3214 | array.finishAndAddTo(fields); | |||
3215 | ||||
3216 | llvm::Constant *GS = | |||
3217 | fields.finishAndCreateGlobal("", CharUnits::fromQuantity(4)); | |||
3218 | llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy); | |||
3219 | return ptr; | |||
3220 | } | |||
3221 | ||||
3222 | llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(const | |||
3223 | ObjCCategoryDecl *OCD) { | |||
3224 | SmallVector<std::string, 16> Protocols; | |||
3225 | for (const auto *PD : OCD->getReferencedProtocols()) | |||
3226 | Protocols.push_back(PD->getNameAsString()); | |||
3227 | return GenerateProtocolList(Protocols); | |||
3228 | } | |||
3229 | ||||
3230 | void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { | |||
3231 | const ObjCInterfaceDecl *Class = OCD->getClassInterface(); | |||
3232 | std::string ClassName = Class->getNameAsString(); | |||
3233 | std::string CategoryName = OCD->getNameAsString(); | |||
3234 | ||||
3235 | // Collect the names of referenced protocols | |||
3236 | const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl(); | |||
3237 | ||||
3238 | ConstantInitBuilder Builder(CGM); | |||
3239 | auto Elements = Builder.beginStruct(); | |||
3240 | Elements.add(MakeConstantString(CategoryName)); | |||
3241 | Elements.add(MakeConstantString(ClassName)); | |||
3242 | // Instance method list | |||
3243 | SmallVector<ObjCMethodDecl*, 16> InstanceMethods; | |||
3244 | InstanceMethods.insert(InstanceMethods.begin(), OCD->instmeth_begin(), | |||
3245 | OCD->instmeth_end()); | |||
3246 | Elements.addBitCast( | |||
3247 | GenerateMethodList(ClassName, CategoryName, InstanceMethods, false), | |||
3248 | PtrTy); | |||
3249 | // Class method list | |||
3250 | ||||
3251 | SmallVector<ObjCMethodDecl*, 16> ClassMethods; | |||
3252 | ClassMethods.insert(ClassMethods.begin(), OCD->classmeth_begin(), | |||
3253 | OCD->classmeth_end()); | |||
3254 | Elements.addBitCast( | |||
3255 | GenerateMethodList(ClassName, CategoryName, ClassMethods, true), | |||
3256 | PtrTy); | |||
3257 | // Protocol list | |||
3258 | Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy); | |||
3259 | if (isRuntime(ObjCRuntime::GNUstep, 2)) { | |||
3260 | const ObjCCategoryDecl *Category = | |||
3261 | Class->FindCategoryDeclaration(OCD->getIdentifier()); | |||
3262 | if (Category) { | |||
3263 | // Instance properties | |||
3264 | Elements.addBitCast(GeneratePropertyList(OCD, Category, false), PtrTy); | |||
3265 | // Class properties | |||
3266 | Elements.addBitCast(GeneratePropertyList(OCD, Category, true), PtrTy); | |||
3267 | } else { | |||
3268 | Elements.addNullPointer(PtrTy); | |||
3269 | Elements.addNullPointer(PtrTy); | |||
3270 | } | |||
3271 | } | |||
3272 | ||||
3273 | Categories.push_back(llvm::ConstantExpr::getBitCast( | |||
3274 | Elements.finishAndCreateGlobal( | |||
3275 | std::string(".objc_category_")+ClassName+CategoryName, | |||
3276 | CGM.getPointerAlign()), | |||
3277 | PtrTy)); | |||
3278 | } | |||
3279 | ||||
3280 | llvm::Constant *CGObjCGNU::GeneratePropertyList(const Decl *Container, | |||
3281 | const ObjCContainerDecl *OCD, | |||
3282 | bool isClassProperty, | |||
3283 | bool protocolOptionalProperties) { | |||
3284 | ||||
3285 | SmallVector<const ObjCPropertyDecl *, 16> Properties; | |||
3286 | llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; | |||
3287 | bool isProtocol = isa<ObjCProtocolDecl>(OCD); | |||
3288 | ASTContext &Context = CGM.getContext(); | |||
3289 | ||||
3290 | std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties | |||
3291 | = [&](const ObjCProtocolDecl *Proto) { | |||
3292 | for (const auto *P : Proto->protocols()) | |||
3293 | collectProtocolProperties(P); | |||
3294 | for (const auto *PD : Proto->properties()) { | |||
3295 | if (isClassProperty != PD->isClassProperty()) | |||
3296 | continue; | |||
3297 | // Skip any properties that are declared in protocols that this class | |||
3298 | // conforms to but are not actually implemented by this class. | |||
3299 | if (!isProtocol && !Context.getObjCPropertyImplDeclForPropertyDecl(PD, Container)) | |||
3300 | continue; | |||
3301 | if (!PropertySet.insert(PD->getIdentifier()).second) | |||
3302 | continue; | |||
3303 | Properties.push_back(PD); | |||
3304 | } | |||
3305 | }; | |||
3306 | ||||
3307 | if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) | |||
3308 | for (const ObjCCategoryDecl *ClassExt : OID->known_extensions()) | |||
3309 | for (auto *PD : ClassExt->properties()) { | |||
3310 | if (isClassProperty != PD->isClassProperty()) | |||
3311 | continue; | |||
3312 | PropertySet.insert(PD->getIdentifier()); | |||
3313 | Properties.push_back(PD); | |||
3314 | } | |||
3315 | ||||
3316 | for (const auto *PD : OCD->properties()) { | |||
3317 | if (isClassProperty != PD->isClassProperty()) | |||
3318 | continue; | |||
3319 | // If we're generating a list for a protocol, skip optional / required ones | |||
3320 | // when generating the other list. | |||
3321 | if (isProtocol && (protocolOptionalProperties != PD->isOptional())) | |||
3322 | continue; | |||
3323 | // Don't emit duplicate metadata for properties that were already in a | |||
3324 | // class extension. | |||
3325 | if (!PropertySet.insert(PD->getIdentifier()).second) | |||
3326 | continue; | |||
3327 | ||||
3328 | Properties.push_back(PD); | |||
3329 | } | |||
3330 | ||||
3331 | if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) | |||
3332 | for (const auto *P : OID->all_referenced_protocols()) | |||
3333 | collectProtocolProperties(P); | |||
3334 | else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) | |||
3335 | for (const auto *P : CD->protocols()) | |||
3336 | collectProtocolProperties(P); | |||
3337 | ||||
3338 | auto numProperties = Properties.size(); | |||
3339 | ||||
3340 | if (numProperties == 0) | |||
3341 | return NULLPtr; | |||
3342 | ||||
3343 | ConstantInitBuilder builder(CGM); | |||
3344 | auto propertyList = builder.beginStruct(); | |||
3345 | auto properties = PushPropertyListHeader(propertyList, numProperties); | |||
3346 | ||||
3347 | // Add all of the property methods need adding to the method list and to the | |||
3348 | // property metadata list. | |||
3349 | for (auto *property : Properties) { | |||
3350 | bool isSynthesized = false; | |||
3351 | bool isDynamic = false; | |||
3352 | if (!isProtocol) { | |||
3353 | auto *propertyImpl = Context.getObjCPropertyImplDeclForPropertyDecl(property, Container); | |||
3354 | if (propertyImpl) { | |||
3355 | isSynthesized = (propertyImpl->getPropertyImplementation() == | |||
3356 | ObjCPropertyImplDecl::Synthesize); | |||
3357 | isDynamic = (propertyImpl->getPropertyImplementation() == | |||
3358 | ObjCPropertyImplDecl::Dynamic); | |||
3359 | } | |||
3360 | } | |||
3361 | PushProperty(properties, property, Container, isSynthesized, isDynamic); | |||
3362 | } | |||
3363 | properties.finishAndAddTo(propertyList); | |||
3364 | ||||
3365 | return propertyList.finishAndCreateGlobal(".objc_property_list", | |||
3366 | CGM.getPointerAlign()); | |||
3367 | } | |||
3368 | ||||
3369 | void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) { | |||
3370 | // Get the class declaration for which the alias is specified. | |||
3371 | ObjCInterfaceDecl *ClassDecl = | |||
3372 | const_cast<ObjCInterfaceDecl *>(OAD->getClassInterface()); | |||
3373 | ClassAliases.emplace_back(ClassDecl->getNameAsString(), | |||
3374 | OAD->getNameAsString()); | |||
3375 | } | |||
3376 | ||||
3377 | void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { | |||
3378 | ASTContext &Context = CGM.getContext(); | |||
3379 | ||||
3380 | // Get the superclass name. | |||
3381 | const ObjCInterfaceDecl * SuperClassDecl = | |||
3382 | OID->getClassInterface()->getSuperClass(); | |||
3383 | std::string SuperClassName; | |||
3384 | if (SuperClassDecl) { | |||
3385 | SuperClassName = SuperClassDecl->getNameAsString(); | |||
3386 | EmitClassRef(SuperClassName); | |||
3387 | } | |||
3388 | ||||
3389 | // Get the class name | |||
3390 | ObjCInterfaceDecl *ClassDecl = | |||
3391 | const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); | |||
3392 | std::string ClassName = ClassDecl->getNameAsString(); | |||
3393 | ||||
3394 | // Emit the symbol that is used to generate linker errors if this class is | |||
3395 | // referenced in other modules but not declared. | |||
3396 | std::string classSymbolName = "__objc_class_name_" + ClassName; | |||
3397 | if (auto *symbol = TheModule.getGlobalVariable(classSymbolName)) { | |||
3398 | symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0)); | |||
3399 | } else { | |||
3400 | new llvm::GlobalVariable(TheModule, LongTy, false, | |||
3401 | llvm::GlobalValue::ExternalLinkage, | |||
3402 | llvm::ConstantInt::get(LongTy, 0), | |||
3403 | classSymbolName); | |||
3404 | } | |||
3405 | ||||
3406 | // Get the size of instances. | |||
3407 | int instanceSize = | |||
3408 | Context.getASTObjCImplementationLayout(OID).getSize().getQuantity(); | |||
3409 | ||||
3410 | // Collect information about instance variables. | |||
3411 | SmallVector<llvm::Constant*, 16> IvarNames; | |||
3412 | SmallVector<llvm::Constant*, 16> IvarTypes; | |||
3413 | SmallVector<llvm::Constant*, 16> IvarOffsets; | |||
3414 | SmallVector<llvm::Constant*, 16> IvarAligns; | |||
3415 | SmallVector<Qualifiers::ObjCLifetime, 16> IvarOwnership; | |||
3416 | ||||
3417 | ConstantInitBuilder IvarOffsetBuilder(CGM); | |||
3418 | auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy); | |||
3419 | SmallVector<bool, 16> WeakIvars; | |||
3420 | SmallVector<bool, 16> StrongIvars; | |||
3421 | ||||
3422 | int superInstanceSize = !SuperClassDecl ? 0 : | |||
3423 | Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity(); | |||
3424 | // For non-fragile ivars, set the instance size to 0 - {the size of just this | |||
3425 | // class}. The runtime will then set this to the correct value on load. | |||
3426 | if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { | |||
3427 | instanceSize = 0 - (instanceSize - superInstanceSize); | |||
3428 | } | |||
3429 | ||||
3430 | for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD; | |||
3431 | IVD = IVD->getNextIvar()) { | |||
3432 | // Store the name | |||
3433 | IvarNames.push_back(MakeConstantString(IVD->getNameAsString())); | |||
3434 | // Get the type encoding for this ivar | |||
3435 | std::string TypeStr; | |||
3436 | Context.getObjCEncodingForType(IVD->getType(), TypeStr, IVD); | |||
3437 | IvarTypes.push_back(MakeConstantString(TypeStr)); | |||
3438 | IvarAligns.push_back(llvm::ConstantInt::get(IntTy, | |||
3439 | Context.getTypeSize(IVD->getType()))); | |||
3440 | // Get the offset | |||
3441 | uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD); | |||
3442 | uint64_t Offset = BaseOffset; | |||
3443 | if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { | |||
3444 | Offset = BaseOffset - superInstanceSize; | |||
3445 | } | |||
3446 | llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset); | |||
3447 | // Create the direct offset value | |||
3448 | std::string OffsetName = "__objc_ivar_offset_value_" + ClassName +"." + | |||
3449 | IVD->getNameAsString(); | |||
3450 | ||||
3451 | llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName); | |||
3452 | if (OffsetVar) { | |||
3453 | OffsetVar->setInitializer(OffsetValue); | |||
3454 | // If this is the real definition, change its linkage type so that | |||
3455 | // different modules will use this one, rather than their private | |||
3456 | // copy. | |||
3457 | OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage); | |||
3458 | } else | |||
3459 | OffsetVar = new llvm::GlobalVariable(TheModule, Int32Ty, | |||
3460 | false, llvm::GlobalValue::ExternalLinkage, | |||
3461 | OffsetValue, OffsetName); | |||
3462 | IvarOffsets.push_back(OffsetValue); | |||
3463 | IvarOffsetValues.add(OffsetVar); | |||
3464 | Qualifiers::ObjCLifetime lt = IVD->getType().getQualifiers().getObjCLifetime(); | |||
3465 | IvarOwnership.push_back(lt); | |||
3466 | switch (lt) { | |||
3467 | case Qualifiers::OCL_Strong: | |||
3468 | StrongIvars.push_back(true); | |||
3469 | WeakIvars.push_back(false); | |||
3470 | break; | |||
3471 | case Qualifiers::OCL_Weak: | |||
3472 | StrongIvars.push_back(false); | |||
3473 | WeakIvars.push_back(true); | |||
3474 | break; | |||
3475 | default: | |||
3476 | StrongIvars.push_back(false); | |||
3477 | WeakIvars.push_back(false); | |||
3478 | } | |||
3479 | } | |||
3480 | llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars); | |||
3481 | llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars); | |||
3482 | llvm::GlobalVariable *IvarOffsetArray = | |||
3483 | IvarOffsetValues.finishAndCreateGlobal(".ivar.offsets", | |||
3484 | CGM.getPointerAlign()); | |||
3485 | ||||
3486 | // Collect information about instance methods | |||
3487 | SmallVector<const ObjCMethodDecl*, 16> InstanceMethods; | |||
3488 | InstanceMethods.insert(InstanceMethods.begin(), OID->instmeth_begin(), | |||
3489 | OID->instmeth_end()); | |||
3490 | ||||
3491 | SmallVector<const ObjCMethodDecl*, 16> ClassMethods; | |||
3492 | ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(), | |||
3493 | OID->classmeth_end()); | |||
3494 | ||||
3495 | // Collect the same information about synthesized properties, which don't | |||
3496 | // show up in the instance method lists. | |||
3497 | for (auto *propertyImpl : OID->property_impls()) | |||
3498 | if (propertyImpl->getPropertyImplementation() == | |||
3499 | ObjCPropertyImplDecl::Synthesize) { | |||
3500 | auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) { | |||
3501 | if (accessor) | |||
3502 | InstanceMethods.push_back(accessor); | |||
3503 | }; | |||
3504 | addPropertyMethod(propertyImpl->getGetterMethodDecl()); | |||
3505 | addPropertyMethod(propertyImpl->getSetterMethodDecl()); | |||
3506 | } | |||
3507 | ||||
3508 | llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl); | |||
3509 | ||||
3510 | // Collect the names of referenced protocols | |||
3511 | SmallVector<std::string, 16> Protocols; | |||
3512 | for (const auto *I : ClassDecl->protocols()) | |||
3513 | Protocols.push_back(I->getNameAsString()); | |||
3514 | ||||
3515 | // Get the superclass pointer. | |||
3516 | llvm::Constant *SuperClass; | |||
3517 | if (!SuperClassName.empty()) { | |||
3518 | SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); | |||
3519 | } else { | |||
3520 | SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); | |||
3521 | } | |||
3522 | // Empty vector used to construct empty method lists | |||
3523 | SmallVector<llvm::Constant*, 1> empty; | |||
3524 | // Generate the method and instance variable lists | |||
3525 | llvm::Constant *MethodList = GenerateMethodList(ClassName, "", | |||
3526 | InstanceMethods, false); | |||
3527 | llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", | |||
3528 | ClassMethods, true); | |||
3529 | llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, | |||
3530 | IvarOffsets, IvarAligns, IvarOwnership); | |||
3531 | // Irrespective of whether we are compiling for a fragile or non-fragile ABI, | |||
3532 | // we emit a symbol containing the offset for each ivar in the class. This | |||
3533 | // allows code compiled for the non-Fragile ABI to inherit from code compiled | |||
3534 | // for the legacy ABI, without causing problems. The converse is also | |||
3535 | // possible, but causes all ivar accesses to be fragile. | |||
3536 | ||||
3537 | // Offset pointer for getting at the correct field in the ivar list when | |||
3538 | // setting up the alias. These are: The base address for the global, the | |||
3539 | // ivar array (second field), the ivar in this list (set for each ivar), and | |||
3540 | // the offset (third field in ivar structure) | |||
3541 | llvm::Type *IndexTy = Int32Ty; | |||
3542 | llvm::Constant *offsetPointerIndexes[] = {Zeros[0], | |||
3543 | llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1), nullptr, | |||
3544 | llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) }; | |||
3545 | ||||
3546 | unsigned ivarIndex = 0; | |||
3547 | for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD; | |||
3548 | IVD = IVD->getNextIvar()) { | |||
3549 | const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD); | |||
3550 | offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex); | |||
3551 | // Get the correct ivar field | |||
3552 | llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr( | |||
3553 | cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList, | |||
3554 | offsetPointerIndexes); | |||
3555 | // Get the existing variable, if one exists. | |||
3556 | llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name); | |||
3557 | if (offset) { | |||
3558 | offset->setInitializer(offsetValue); | |||
3559 | // If this is the real definition, change its linkage type so that | |||
3560 | // different modules will use this one, rather than their private | |||
3561 | // copy. | |||
3562 | offset->setLinkage(llvm::GlobalValue::ExternalLinkage); | |||
3563 | } else | |||
3564 | // Add a new alias if there isn't one already. | |||
3565 | new llvm::GlobalVariable(TheModule, offsetValue->getType(), | |||
3566 | false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name); | |||
3567 | ++ivarIndex; | |||
3568 | } | |||
3569 | llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0); | |||
3570 | ||||
3571 | //Generate metaclass for class methods | |||
3572 | llvm::Constant *MetaClassStruct = GenerateClassStructure( | |||
3573 | NULLPtr, NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0], | |||
3574 | NULLPtr, ClassMethodList, NULLPtr, NULLPtr, | |||
3575 | GeneratePropertyList(OID, ClassDecl, true), ZeroPtr, ZeroPtr, true); | |||
3576 | CGM.setGVProperties(cast<llvm::GlobalValue>(MetaClassStruct), | |||
3577 | OID->getClassInterface()); | |||
3578 | ||||
3579 | // Generate the class structure | |||
3580 | llvm::Constant *ClassStruct = GenerateClassStructure( | |||
3581 | MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(), nullptr, | |||
3582 | llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList, | |||
3583 | GenerateProtocolList(Protocols), IvarOffsetArray, Properties, | |||
3584 | StrongIvarBitmap, WeakIvarBitmap); | |||
3585 | CGM.setGVProperties(cast<llvm::GlobalValue>(ClassStruct), | |||
3586 | OID->getClassInterface()); | |||
3587 | ||||
3588 | // Resolve the class aliases, if they exist. | |||
3589 | if (ClassPtrAlias) { | |||
3590 | ClassPtrAlias->replaceAllUsesWith( | |||
3591 | llvm::ConstantExpr::getBitCast(ClassStruct, IdTy)); | |||
3592 | ClassPtrAlias->eraseFromParent(); | |||
3593 | ClassPtrAlias = nullptr; | |||
3594 | } | |||
3595 | if (MetaClassPtrAlias) { | |||
3596 | MetaClassPtrAlias->replaceAllUsesWith( | |||
3597 | llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy)); | |||
3598 | MetaClassPtrAlias->eraseFromParent(); | |||
3599 | MetaClassPtrAlias = nullptr; | |||
3600 | } | |||
3601 | ||||
3602 | // Add class structure to list to be added to the symtab later | |||
3603 | ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); | |||
3604 | Classes.push_back(ClassStruct); | |||
3605 | } | |||
3606 | ||||
3607 | llvm::Function *CGObjCGNU::ModuleInitFunction() { | |||
3608 | // Only emit an ObjC load function if no Objective-C stuff has been called | |||
3609 | if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && | |||
3610 | ExistingProtocols.empty() && SelectorTable.empty()) | |||
3611 | return nullptr; | |||
3612 | ||||
3613 | // Add all referenced protocols to a category. | |||
3614 | GenerateProtocolHolderCategory(); | |||
3615 | ||||
3616 | llvm::StructType *selStructTy = | |||
3617 | dyn_cast<llvm::StructType>(SelectorTy->getElementType()); | |||
3618 | llvm::Type *selStructPtrTy = SelectorTy; | |||
3619 | if (!selStructTy) { | |||
3620 | selStructTy = llvm::StructType::get(CGM.getLLVMContext(), | |||
3621 | { PtrToInt8Ty, PtrToInt8Ty }); | |||
3622 | selStructPtrTy = llvm::PointerType::getUnqual(selStructTy); | |||
3623 | } | |||
3624 | ||||
3625 | // Generate statics list: | |||
3626 | llvm::Constant *statics = NULLPtr; | |||
3627 | if (!ConstantStrings.empty()) { | |||
3628 | llvm::GlobalVariable *fileStatics = [&] { | |||
3629 | ConstantInitBuilder builder(CGM); | |||
3630 | auto staticsStruct = builder.beginStruct(); | |||
3631 | ||||
3632 | StringRef stringClass = CGM.getLangOpts().ObjCConstantStringClass; | |||
3633 | if (stringClass.empty()) stringClass = "NXConstantString"; | |||
3634 | staticsStruct.add(MakeConstantString(stringClass, | |||
3635 | ".objc_static_class_name")); | |||
3636 | ||||
3637 | auto array = staticsStruct.beginArray(); | |||
3638 | array.addAll(ConstantStrings); | |||
3639 | array.add(NULLPtr); | |||
3640 | array.finishAndAddTo(staticsStruct); | |||
3641 | ||||
3642 | return staticsStruct.finishAndCreateGlobal(".objc_statics", | |||
3643 | CGM.getPointerAlign()); | |||
3644 | }(); | |||
3645 | ||||
3646 | ConstantInitBuilder builder(CGM); | |||
3647 | auto allStaticsArray = builder.beginArray(fileStatics->getType()); | |||
3648 | allStaticsArray.add(fileStatics); | |||
3649 | allStaticsArray.addNullPointer(fileStatics->getType()); | |||
3650 | ||||
3651 | statics = allStaticsArray.finishAndCreateGlobal(".objc_statics_ptr", | |||
3652 | CGM.getPointerAlign()); | |||
3653 | statics = llvm::ConstantExpr::getBitCast(statics, PtrTy); | |||
3654 | } | |||
3655 | ||||
3656 | // Array of classes, categories, and constant objects. | |||
3657 | ||||
3658 | SmallVector<llvm::GlobalAlias*, 16> selectorAliases; | |||
3659 | unsigned selectorCount; | |||
3660 | ||||
3661 | // Pointer to an array of selectors used in this module. | |||
3662 | llvm::GlobalVariable *selectorList = [&] { | |||
3663 | ConstantInitBuilder builder(CGM); | |||
3664 | auto selectors = builder.beginArray(selStructTy); | |||
3665 | auto &table = SelectorTable; // MSVC workaround | |||
3666 | std::vector<Selector> allSelectors; | |||
3667 | for (auto &entry : table) | |||
3668 | allSelectors.push_back(entry.first); | |||
3669 | llvm::sort(allSelectors); | |||
3670 | ||||
3671 | for (auto &untypedSel : allSelectors) { | |||
3672 | std::string selNameStr = untypedSel.getAsString(); | |||
3673 | llvm::Constant *selName = ExportUniqueString(selNameStr, ".objc_sel_name"); | |||
3674 | ||||
3675 | for (TypedSelector &sel : table[untypedSel]) { | |||
3676 | llvm::Constant *selectorTypeEncoding = NULLPtr; | |||
3677 | if (!sel.first.empty()) | |||
3678 | selectorTypeEncoding = | |||
3679 | MakeConstantString(sel.first, ".objc_sel_types"); | |||
3680 | ||||
3681 | auto selStruct = selectors.beginStruct(selStructTy); | |||
3682 | selStruct.add(selName); | |||
3683 | selStruct.add(selectorTypeEncoding); | |||
3684 | selStruct.finishAndAddTo(selectors); | |||
3685 | ||||
3686 | // Store the selector alias for later replacement | |||
3687 | selectorAliases.push_back(sel.second); | |||
3688 | } | |||
3689 | } | |||
3690 | ||||
3691 | // Remember the number of entries in the selector table. | |||
3692 | selectorCount = selectors.size(); | |||
3693 | ||||
3694 | // NULL-terminate the selector list. This should not actually be required, | |||
3695 | // because the selector list has a length field. Unfortunately, the GCC | |||
3696 | // runtime decides to ignore the length field and expects a NULL terminator, | |||
3697 | // and GCC cooperates with this by always setting the length to 0. | |||
3698 | auto selStruct = selectors.beginStruct(selStructTy); | |||
3699 | selStruct.add(NULLPtr); | |||
3700 | selStruct.add(NULLPtr); | |||
3701 | selStruct.finishAndAddTo(selectors); | |||
3702 | ||||
3703 | return selectors.finishAndCreateGlobal(".objc_selector_list", | |||
3704 | CGM.getPointerAlign()); | |||
3705 | }(); | |||
3706 | ||||
3707 | // Now that all of the static selectors exist, create pointers to them. | |||
3708 | for (unsigned i = 0; i < selectorCount; ++i) { | |||
3709 | llvm::Constant *idxs[] = { | |||
3710 | Zeros[0], | |||
3711 | llvm::ConstantInt::get(Int32Ty, i) | |||
3712 | }; | |||
3713 | // FIXME: We're generating redundant loads and stores here! | |||
3714 | llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr( | |||
3715 | selectorList->getValueType(), selectorList, idxs); | |||
3716 | // If selectors are defined as an opaque type, cast the pointer to this | |||
3717 | // type. | |||
3718 | selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy); | |||
3719 | selectorAliases[i]->replaceAllUsesWith(selPtr); | |||
3720 | selectorAliases[i]->eraseFromParent(); | |||
3721 | } | |||
3722 | ||||
3723 | llvm::GlobalVariable *symtab = [&] { | |||
3724 | ConstantInitBuilder builder(CGM); | |||
3725 | auto symtab = builder.beginStruct(); | |||
3726 | ||||
3727 | // Number of static selectors | |||
3728 | symtab.addInt(LongTy, selectorCount); | |||
3729 | ||||
3730 | symtab.addBitCast(selectorList, selStructPtrTy); | |||
3731 | ||||
3732 | // Number of classes defined. | |||
3733 | symtab.addInt(CGM.Int16Ty, Classes.size()); | |||
3734 | // Number of categories defined | |||
3735 | symtab.addInt(CGM.Int16Ty, Categories.size()); | |||
3736 | ||||
3737 | // Create an array of classes, then categories, then static object instances | |||
3738 | auto classList = symtab.beginArray(PtrToInt8Ty); | |||
3739 | classList.addAll(Classes); | |||
3740 | classList.addAll(Categories); | |||
3741 | // NULL-terminated list of static object instances (mainly constant strings) | |||
3742 | classList.add(statics); | |||
3743 | classList.add(NULLPtr); | |||
3744 | classList.finishAndAddTo(symtab); | |||
3745 | ||||
3746 | // Construct the symbol table. | |||
3747 | return symtab.finishAndCreateGlobal("", CGM.getPointerAlign()); | |||
3748 | }(); | |||
3749 | ||||
3750 | // The symbol table is contained in a module which has some version-checking | |||
3751 | // constants | |||
3752 | llvm::Constant *module = [&] { | |||
3753 | llvm::Type *moduleEltTys[] = { | |||
3754 | LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy | |||
3755 | }; | |||
3756 | llvm::StructType *moduleTy = | |||
3757 | llvm::StructType::get(CGM.getLLVMContext(), | |||
3758 | makeArrayRef(moduleEltTys).drop_back(unsigned(RuntimeVersion < 10))); | |||
3759 | ||||
3760 | ConstantInitBuilder builder(CGM); | |||
3761 | auto module = builder.beginStruct(moduleTy); | |||
3762 | // Runtime version, used for ABI compatibility checking. | |||
3763 | module.addInt(LongTy, RuntimeVersion); | |||
3764 | // sizeof(ModuleTy) | |||
3765 | module.addInt(LongTy, CGM.getDataLayout().getTypeStoreSize(moduleTy)); | |||
3766 | ||||
3767 | // The path to the source file where this module was declared | |||
3768 | SourceManager &SM = CGM.getContext().getSourceManager(); | |||
3769 | const FileEntry *mainFile = SM.getFileEntryForID(SM.getMainFileID()); | |||
3770 | std::string path = | |||
3771 | (Twine(mainFile->getDir()->getName()) + "/" + mainFile->getName()).str(); | |||
3772 | module.add(MakeConstantString(path, ".objc_source_file_name")); | |||
3773 | module.add(symtab); | |||
3774 | ||||
3775 | if (RuntimeVersion >= 10) { | |||
3776 | switch (CGM.getLangOpts().getGC()) { | |||
3777 | case LangOptions::GCOnly: | |||
3778 | module.addInt(IntTy, 2); | |||
3779 | break; | |||
3780 | case LangOptions::NonGC: | |||
3781 | if (CGM.getLangOpts().ObjCAutoRefCount) | |||
3782 | module.addInt(IntTy, 1); | |||
3783 | else | |||
3784 | module.addInt(IntTy, 0); | |||
3785 | break; | |||
3786 | case LangOptions::HybridGC: | |||
3787 | module.addInt(IntTy, 1); | |||
3788 | break; | |||
3789 | } | |||
3790 | } | |||
3791 | ||||
3792 | return module.finishAndCreateGlobal("", CGM.getPointerAlign()); | |||
3793 | }(); | |||
3794 | ||||
3795 | // Create the load function calling the runtime entry point with the module | |||
3796 | // structure | |||
3797 | llvm::Function * LoadFunction = llvm::Function::Create( | |||
3798 | llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false), | |||
3799 | llvm::GlobalValue::InternalLinkage, ".objc_load_function", | |||
3800 | &TheModule); | |||
3801 | llvm::BasicBlock *EntryBB = | |||
3802 | llvm::BasicBlock::Create(VMContext, "entry", LoadFunction); | |||
3803 | CGBuilderTy Builder(CGM, VMContext); | |||
3804 | Builder.SetInsertPoint(EntryBB); | |||
3805 | ||||
3806 | llvm::FunctionType *FT = | |||
3807 | llvm::FunctionType::get(Builder.getVoidTy(), module->getType(), true); | |||
3808 | llvm::FunctionCallee Register = | |||
3809 | CGM.CreateRuntimeFunction(FT, "__objc_exec_class"); | |||
3810 | Builder.CreateCall(Register, module); | |||
3811 | ||||
3812 | if (!ClassAliases.empty()) { | |||
3813 | llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty}; | |||
3814 | llvm::FunctionType *RegisterAliasTy = | |||
3815 | llvm::FunctionType::get(Builder.getVoidTy(), | |||
3816 | ArgTypes, false); | |||
3817 | llvm::Function *RegisterAlias = llvm::Function::Create( | |||
3818 | RegisterAliasTy, | |||
3819 | llvm::GlobalValue::ExternalWeakLinkage, "class_registerAlias_np", | |||
3820 | &TheModule); | |||
3821 | llvm::BasicBlock *AliasBB = | |||
3822 | llvm::BasicBlock::Create(VMContext, "alias", LoadFunction); | |||
3823 | llvm::BasicBlock *NoAliasBB = | |||
3824 | llvm::BasicBlock::Create(VMContext, "no_alias", LoadFunction); | |||
3825 | ||||
3826 | // Branch based on whether the runtime provided class_registerAlias_np() | |||
3827 | llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias, | |||
3828 | llvm::Constant::getNullValue(RegisterAlias->getType())); | |||
3829 | Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB); | |||
3830 | ||||
3831 | // The true branch (has alias registration function): | |||
3832 | Builder.SetInsertPoint(AliasBB); | |||
3833 | // Emit alias registration calls: | |||
3834 | for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin(); | |||
3835 | iter != ClassAliases.end(); ++iter) { | |||
3836 | llvm::Constant *TheClass = | |||
3837 | TheModule.getGlobalVariable("_OBJC_CLASS_" + iter->first, true); | |||
3838 | if (TheClass) { | |||
3839 | TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy); | |||
3840 | Builder.CreateCall(RegisterAlias, | |||
3841 | {TheClass, MakeConstantString(iter->second)}); | |||
3842 | } | |||
3843 | } | |||
3844 | // Jump to end: | |||
3845 | Builder.CreateBr(NoAliasBB); | |||
3846 | ||||
3847 | // Missing alias registration function, just return from the function: | |||
3848 | Builder.SetInsertPoint(NoAliasBB); | |||
3849 | } | |||
3850 | Builder.CreateRetVoid(); | |||
3851 | ||||
3852 | return LoadFunction; | |||
3853 | } | |||
3854 | ||||
3855 | llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, | |||
3856 | const ObjCContainerDecl *CD) { | |||
3857 | const ObjCCategoryImplDecl *OCD = | |||
3858 | dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext()); | |||
3859 | StringRef CategoryName = OCD ? OCD->getName() : ""; | |||
3860 | StringRef ClassName = CD->getName(); | |||
3861 | Selector MethodName = OMD->getSelector(); | |||
3862 | bool isClassMethod = !OMD->isInstanceMethod(); | |||
3863 | ||||
3864 | CodeGenTypes &Types = CGM.getTypes(); | |||
3865 | llvm::FunctionType *MethodTy = | |||
3866 | Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD)); | |||
3867 | std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, | |||
3868 | MethodName, isClassMethod); | |||
3869 | ||||
3870 | llvm::Function *Method | |||
3871 | = llvm::Function::Create(MethodTy, | |||
3872 | llvm::GlobalValue::InternalLinkage, | |||
3873 | FunctionName, | |||
3874 | &TheModule); | |||
3875 | return Method; | |||
3876 | } | |||
3877 | ||||
3878 | void CGObjCGNU::GenerateDirectMethodPrologue(CodeGenFunction &CGF, | |||
3879 | llvm::Function *Fn, | |||
3880 | const ObjCMethodDecl *OMD, | |||
3881 | const ObjCContainerDecl *CD) { | |||
3882 | // GNU runtime doesn't support direct calls at this time | |||
3883 | } | |||
3884 | ||||
3885 | llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() { | |||
3886 | return GetPropertyFn; | |||
3887 | } | |||
3888 | ||||
3889 | llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() { | |||
3890 | return SetPropertyFn; | |||
3891 | } | |||
3892 | ||||
3893 | llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic, | |||
3894 | bool copy) { | |||
3895 | return nullptr; | |||
3896 | } | |||
3897 | ||||
3898 | llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() { | |||
3899 | return GetStructPropertyFn; | |||
3900 | } | |||
3901 | ||||
3902 | llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() { | |||
3903 | return SetStructPropertyFn; | |||
3904 | } | |||
3905 | ||||
3906 | llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() { | |||
3907 | return nullptr; | |||
3908 | } | |||
3909 | ||||
3910 | llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() { | |||
3911 | return nullptr; | |||
3912 | } | |||
3913 | ||||
3914 | llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() { | |||
3915 | return EnumerationMutationFn; | |||
3916 | } | |||
3917 | ||||
3918 | void CGObjCGNU::EmitSynchronizedStmt(CodeGenFunction &CGF, | |||
3919 | const ObjCAtSynchronizedStmt &S) { | |||
3920 | EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn); | |||
3921 | } | |||
3922 | ||||
3923 | ||||
3924 | void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF, | |||
3925 | const ObjCAtTryStmt &S) { | |||
3926 | // Unlike the Apple non-fragile runtimes, which also uses | |||
3927 | // unwind-based zero cost exceptions, the GNU Objective C runtime's | |||
3928 | // EH support isn't a veneer over C++ EH. Instead, exception | |||
3929 | // objects are created by objc_exception_throw and destroyed by | |||
3930 | // the personality function; this avoids the need for bracketing | |||
3931 | // catch handlers with calls to __blah_begin_catch/__blah_end_catch | |||
3932 | // (or even _Unwind_DeleteException), but probably doesn't | |||
3933 | // interoperate very well with foreign exceptions. | |||
3934 | // | |||
3935 | // In Objective-C++ mode, we actually emit something equivalent to the C++ | |||
3936 | // exception handler. | |||
3937 | EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn); | |||
3938 | } | |||
3939 | ||||
3940 | void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, | |||
3941 | const ObjCAtThrowStmt &S, | |||
3942 | bool ClearInsertionPoint) { | |||
3943 | llvm::Value *ExceptionAsObject; | |||
3944 | bool isRethrow = false; | |||
3945 | ||||
3946 | if (const Expr *ThrowExpr = S.getThrowExpr()) { | |||
3947 | llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); | |||
3948 | ExceptionAsObject = Exception; | |||
3949 | } else { | |||
3950 | assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&(((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack .back()) && "Unexpected rethrow outside @catch block." ) ? static_cast<void> (0) : __assert_fail ("(!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && \"Unexpected rethrow outside @catch block.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 3951, __PRETTY_FUNCTION__)) | |||
3951 | "Unexpected rethrow outside @catch block.")(((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack .back()) && "Unexpected rethrow outside @catch block." ) ? static_cast<void> (0) : __assert_fail ("(!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && \"Unexpected rethrow outside @catch block.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 3951, __PRETTY_FUNCTION__)); | |||
3952 | ExceptionAsObject = CGF.ObjCEHValueStack.back(); | |||
3953 | isRethrow = true; | |||
3954 | } | |||
3955 | if (isRethrow && usesSEHExceptions) { | |||
3956 | // For SEH, ExceptionAsObject may be undef, because the catch handler is | |||
3957 | // not passed it for catchalls and so it is not visible to the catch | |||
3958 | // funclet. The real thrown object will still be live on the stack at this | |||
3959 | // point and will be rethrown. If we are explicitly rethrowing the object | |||
3960 | // that was passed into the `@catch` block, then this code path is not | |||
3961 | // reached and we will instead call `objc_exception_throw` with an explicit | |||
3962 | // argument. | |||
3963 | llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn); | |||
3964 | Throw->setDoesNotReturn(); | |||
3965 | } | |||
3966 | else { | |||
3967 | ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy); | |||
3968 | llvm::CallBase *Throw = | |||
3969 | CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject); | |||
3970 | Throw->setDoesNotReturn(); | |||
3971 | } | |||
3972 | CGF.Builder.CreateUnreachable(); | |||
3973 | if (ClearInsertionPoint) | |||
3974 | CGF.Builder.ClearInsertionPoint(); | |||
3975 | } | |||
3976 | ||||
3977 | llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF, | |||
3978 | Address AddrWeakObj) { | |||
3979 | CGBuilderTy &B = CGF.Builder; | |||
3980 | AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy); | |||
3981 | return B.CreateCall(WeakReadFn, AddrWeakObj.getPointer()); | |||
3982 | } | |||
3983 | ||||
3984 | void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, | |||
3985 | llvm::Value *src, Address dst) { | |||
3986 | CGBuilderTy &B = CGF.Builder; | |||
3987 | src = EnforceType(B, src, IdTy); | |||
3988 | dst = EnforceType(B, dst, PtrToIdTy); | |||
3989 | B.CreateCall(WeakAssignFn, {src, dst.getPointer()}); | |||
3990 | } | |||
3991 | ||||
3992 | void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, | |||
3993 | llvm::Value *src, Address dst, | |||
3994 | bool threadlocal) { | |||
3995 | CGBuilderTy &B = CGF.Builder; | |||
3996 | src = EnforceType(B, src, IdTy); | |||
3997 | dst = EnforceType(B, dst, PtrToIdTy); | |||
3998 | // FIXME. Add threadloca assign API | |||
3999 | assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI")((!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI" ) ? static_cast<void> (0) : __assert_fail ("!threadlocal && \"EmitObjCGlobalAssign - Threal Local API NYI\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 3999, __PRETTY_FUNCTION__)); | |||
4000 | B.CreateCall(GlobalAssignFn, {src, dst.getPointer()}); | |||
4001 | } | |||
4002 | ||||
4003 | void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, | |||
4004 | llvm::Value *src, Address dst, | |||
4005 | llvm::Value *ivarOffset) { | |||
4006 | CGBuilderTy &B = CGF.Builder; | |||
4007 | src = EnforceType(B, src, IdTy); | |||
4008 | dst = EnforceType(B, dst, IdTy); | |||
4009 | B.CreateCall(IvarAssignFn, {src, dst.getPointer(), ivarOffset}); | |||
4010 | } | |||
4011 | ||||
4012 | void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, | |||
4013 | llvm::Value *src, Address dst) { | |||
4014 | CGBuilderTy &B = CGF.Builder; | |||
4015 | src = EnforceType(B, src, IdTy); | |||
4016 | dst = EnforceType(B, dst, PtrToIdTy); | |||
4017 | B.CreateCall(StrongCastAssignFn, {src, dst.getPointer()}); | |||
4018 | } | |||
4019 | ||||
4020 | void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, | |||
4021 | Address DestPtr, | |||
4022 | Address SrcPtr, | |||
4023 | llvm::Value *Size) { | |||
4024 | CGBuilderTy &B = CGF.Builder; | |||
4025 | DestPtr = EnforceType(B, DestPtr, PtrTy); | |||
4026 | SrcPtr = EnforceType(B, SrcPtr, PtrTy); | |||
4027 | ||||
4028 | B.CreateCall(MemMoveFn, {DestPtr.getPointer(), SrcPtr.getPointer(), Size}); | |||
4029 | } | |||
4030 | ||||
4031 | llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( | |||
4032 | const ObjCInterfaceDecl *ID, | |||
4033 | const ObjCIvarDecl *Ivar) { | |||
4034 | const std::string Name = GetIVarOffsetVariableName(ID, Ivar); | |||
4035 | // Emit the variable and initialize it with what we think the correct value | |||
4036 | // is. This allows code compiled with non-fragile ivars to work correctly | |||
4037 | // when linked against code which isn't (most of the time). | |||
4038 | llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); | |||
4039 | if (!IvarOffsetPointer) | |||
4040 | IvarOffsetPointer = new llvm::GlobalVariable(TheModule, | |||
4041 | llvm::Type::getInt32PtrTy(VMContext), false, | |||
4042 | llvm::GlobalValue::ExternalLinkage, nullptr, Name); | |||
4043 | return IvarOffsetPointer; | |||
4044 | } | |||
4045 | ||||
4046 | LValue CGObjCGNU::EmitObjCValueForIvar(CodeGenFunction &CGF, | |||
4047 | QualType ObjectTy, | |||
4048 | llvm::Value *BaseValue, | |||
4049 | const ObjCIvarDecl *Ivar, | |||
4050 | unsigned CVRQualifiers) { | |||
4051 | const ObjCInterfaceDecl *ID = | |||
4052 | ObjectTy->castAs<ObjCObjectType>()->getInterface(); | |||
4053 | return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, | |||
4054 | EmitIvarOffset(CGF, ID, Ivar)); | |||
4055 | } | |||
4056 | ||||
4057 | static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, | |||
4058 | const ObjCInterfaceDecl *OID, | |||
4059 | const ObjCIvarDecl *OIVD) { | |||
4060 | for (const ObjCIvarDecl *next = OID->all_declared_ivar_begin(); next; | |||
4061 | next = next->getNextIvar()) { | |||
4062 | if (OIVD == next) | |||
4063 | return OID; | |||
4064 | } | |||
4065 | ||||
4066 | // Otherwise check in the super class. | |||
4067 | if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) | |||
4068 | return FindIvarInterface(Context, Super, OIVD); | |||
4069 | ||||
4070 | return nullptr; | |||
4071 | } | |||
4072 | ||||
4073 | llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF, | |||
4074 | const ObjCInterfaceDecl *Interface, | |||
4075 | const ObjCIvarDecl *Ivar) { | |||
4076 | if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { | |||
4077 | Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar); | |||
4078 | ||||
4079 | // The MSVC linker cannot have a single global defined as LinkOnceAnyLinkage | |||
4080 | // and ExternalLinkage, so create a reference to the ivar global and rely on | |||
4081 | // the definition being created as part of GenerateClass. | |||
4082 | if (RuntimeVersion < 10 || | |||
4083 | CGF.CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) | |||
4084 | return CGF.Builder.CreateZExtOrBitCast( | |||
4085 | CGF.Builder.CreateAlignedLoad( | |||
4086 | Int32Ty, CGF.Builder.CreateAlignedLoad( | |||
4087 | ObjCIvarOffsetVariable(Interface, Ivar), | |||
4088 | CGF.getPointerAlign(), "ivar"), | |||
4089 | CharUnits::fromQuantity(4)), | |||
4090 | PtrDiffTy); | |||
4091 | std::string name = "__objc_ivar_offset_value_" + | |||
4092 | Interface->getNameAsString() +"." + Ivar->getNameAsString(); | |||
4093 | CharUnits Align = CGM.getIntAlign(); | |||
4094 | llvm::Value *Offset = TheModule.getGlobalVariable(name); | |||
4095 | if (!Offset) { | |||
4096 | auto GV = new llvm::GlobalVariable(TheModule, IntTy, | |||
4097 | false, llvm::GlobalValue::LinkOnceAnyLinkage, | |||
4098 | llvm::Constant::getNullValue(IntTy), name); | |||
4099 | GV->setAlignment(Align.getAsAlign()); | |||
4100 | Offset = GV; | |||
4101 | } | |||
4102 | Offset = CGF.Builder.CreateAlignedLoad(Offset, Align); | |||
4103 | if (Offset->getType() != PtrDiffTy) | |||
4104 | Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); | |||
4105 | return Offset; | |||
4106 | } | |||
4107 | uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); | |||
4108 | return llvm::ConstantInt::get(PtrDiffTy, Offset, /*isSigned*/true); | |||
4109 | } | |||
4110 | ||||
4111 | CGObjCRuntime * | |||
4112 | clang::CodeGen::CreateGNUObjCRuntime(CodeGenModule &CGM) { | |||
4113 | auto Runtime = CGM.getLangOpts().ObjCRuntime; | |||
4114 | switch (Runtime.getKind()) { | |||
4115 | case ObjCRuntime::GNUstep: | |||
4116 | if (Runtime.getVersion() >= VersionTuple(2, 0)) | |||
4117 | return new CGObjCGNUstep2(CGM); | |||
4118 | return new CGObjCGNUstep(CGM); | |||
4119 | ||||
4120 | case ObjCRuntime::GCC: | |||
4121 | return new CGObjCGCC(CGM); | |||
4122 | ||||
4123 | case ObjCRuntime::ObjFW: | |||
4124 | return new CGObjCObjFW(CGM); | |||
4125 | ||||
4126 | case ObjCRuntime::FragileMacOSX: | |||
4127 | case ObjCRuntime::MacOSX: | |||
4128 | case ObjCRuntime::iOS: | |||
4129 | case ObjCRuntime::WatchOS: | |||
4130 | llvm_unreachable("these runtimes are not GNU runtimes")::llvm::llvm_unreachable_internal("these runtimes are not GNU runtimes" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 4130); | |||
4131 | } | |||
4132 | llvm_unreachable("bad runtime")::llvm::llvm_unreachable_internal("bad runtime", "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/clang/lib/CodeGen/CGObjCGNU.cpp" , 4132); | |||
4133 | } |
1 | //===- llvm/IRBuilder.h - Builder for LLVM Instructions ---------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This file defines the IRBuilder class, which is used as a convenient way | |||
10 | // to create LLVM instructions with a consistent and simplified interface. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #ifndef LLVM_IR_IRBUILDER_H | |||
15 | #define LLVM_IR_IRBUILDER_H | |||
16 | ||||
17 | #include "llvm-c/Types.h" | |||
18 | #include "llvm/ADT/ArrayRef.h" | |||
19 | #include "llvm/ADT/None.h" | |||
20 | #include "llvm/ADT/StringRef.h" | |||
21 | #include "llvm/ADT/Twine.h" | |||
22 | #include "llvm/IR/BasicBlock.h" | |||
23 | #include "llvm/IR/Constant.h" | |||
24 | #include "llvm/IR/ConstantFolder.h" | |||
25 | #include "llvm/IR/Constants.h" | |||
26 | #include "llvm/IR/DataLayout.h" | |||
27 | #include "llvm/IR/DebugLoc.h" | |||
28 | #include "llvm/IR/DerivedTypes.h" | |||
29 | #include "llvm/IR/Function.h" | |||
30 | #include "llvm/IR/GlobalVariable.h" | |||
31 | #include "llvm/IR/InstrTypes.h" | |||
32 | #include "llvm/IR/Instruction.h" | |||
33 | #include "llvm/IR/Instructions.h" | |||
34 | #include "llvm/IR/IntrinsicInst.h" | |||
35 | #include "llvm/IR/LLVMContext.h" | |||
36 | #include "llvm/IR/Module.h" | |||
37 | #include "llvm/IR/Operator.h" | |||
38 | #include "llvm/IR/Type.h" | |||
39 | #include "llvm/IR/Value.h" | |||
40 | #include "llvm/IR/ValueHandle.h" | |||
41 | #include "llvm/Support/AtomicOrdering.h" | |||
42 | #include "llvm/Support/CBindingWrapping.h" | |||
43 | #include "llvm/Support/Casting.h" | |||
44 | #include <cassert> | |||
45 | #include <cstddef> | |||
46 | #include <cstdint> | |||
47 | #include <functional> | |||
48 | #include <utility> | |||
49 | ||||
50 | namespace llvm { | |||
51 | ||||
52 | class APInt; | |||
53 | class MDNode; | |||
54 | class Use; | |||
55 | ||||
56 | /// This provides the default implementation of the IRBuilder | |||
57 | /// 'InsertHelper' method that is called whenever an instruction is created by | |||
58 | /// IRBuilder and needs to be inserted. | |||
59 | /// | |||
60 | /// By default, this inserts the instruction at the insertion point. | |||
61 | class IRBuilderDefaultInserter { | |||
62 | protected: | |||
63 | void InsertHelper(Instruction *I, const Twine &Name, | |||
64 | BasicBlock *BB, BasicBlock::iterator InsertPt) const { | |||
65 | if (BB) BB->getInstList().insert(InsertPt, I); | |||
66 | I->setName(Name); | |||
67 | } | |||
68 | }; | |||
69 | ||||
70 | /// Provides an 'InsertHelper' that calls a user-provided callback after | |||
71 | /// performing the default insertion. | |||
72 | class IRBuilderCallbackInserter : IRBuilderDefaultInserter { | |||
73 | std::function<void(Instruction *)> Callback; | |||
74 | ||||
75 | public: | |||
76 | IRBuilderCallbackInserter(std::function<void(Instruction *)> Callback) | |||
77 | : Callback(std::move(Callback)) {} | |||
78 | ||||
79 | protected: | |||
80 | void InsertHelper(Instruction *I, const Twine &Name, | |||
81 | BasicBlock *BB, BasicBlock::iterator InsertPt) const { | |||
82 | IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt); | |||
83 | Callback(I); | |||
84 | } | |||
85 | }; | |||
86 | ||||
87 | /// Common base class shared among various IRBuilders. | |||
88 | class IRBuilderBase { | |||
89 | DebugLoc CurDbgLocation; | |||
90 | ||||
91 | protected: | |||
92 | BasicBlock *BB; | |||
93 | BasicBlock::iterator InsertPt; | |||
94 | LLVMContext &Context; | |||
95 | ||||
96 | MDNode *DefaultFPMathTag; | |||
97 | FastMathFlags FMF; | |||
98 | ||||
99 | bool IsFPConstrained; | |||
100 | fp::ExceptionBehavior DefaultConstrainedExcept; | |||
101 | fp::RoundingMode DefaultConstrainedRounding; | |||
102 | ||||
103 | ArrayRef<OperandBundleDef> DefaultOperandBundles; | |||
104 | ||||
105 | public: | |||
106 | IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr, | |||
107 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
108 | : Context(context), DefaultFPMathTag(FPMathTag), IsFPConstrained(false), | |||
109 | DefaultConstrainedExcept(fp::ebStrict), | |||
110 | DefaultConstrainedRounding(fp::rmDynamic), | |||
111 | DefaultOperandBundles(OpBundles) { | |||
112 | ClearInsertionPoint(); | |||
113 | } | |||
114 | ||||
115 | //===--------------------------------------------------------------------===// | |||
116 | // Builder configuration methods | |||
117 | //===--------------------------------------------------------------------===// | |||
118 | ||||
119 | /// Clear the insertion point: created instructions will not be | |||
120 | /// inserted into a block. | |||
121 | void ClearInsertionPoint() { | |||
122 | BB = nullptr; | |||
123 | InsertPt = BasicBlock::iterator(); | |||
124 | } | |||
125 | ||||
126 | BasicBlock *GetInsertBlock() const { return BB; } | |||
127 | BasicBlock::iterator GetInsertPoint() const { return InsertPt; } | |||
128 | LLVMContext &getContext() const { return Context; } | |||
129 | ||||
130 | /// This specifies that created instructions should be appended to the | |||
131 | /// end of the specified block. | |||
132 | void SetInsertPoint(BasicBlock *TheBB) { | |||
133 | BB = TheBB; | |||
134 | InsertPt = BB->end(); | |||
135 | } | |||
136 | ||||
137 | /// This specifies that created instructions should be inserted before | |||
138 | /// the specified instruction. | |||
139 | void SetInsertPoint(Instruction *I) { | |||
140 | BB = I->getParent(); | |||
141 | InsertPt = I->getIterator(); | |||
142 | assert(InsertPt != BB->end() && "Can't read debug loc from end()")((InsertPt != BB->end() && "Can't read debug loc from end()" ) ? static_cast<void> (0) : __assert_fail ("InsertPt != BB->end() && \"Can't read debug loc from end()\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 142, __PRETTY_FUNCTION__)); | |||
143 | SetCurrentDebugLocation(I->getDebugLoc()); | |||
144 | } | |||
145 | ||||
146 | /// This specifies that created instructions should be inserted at the | |||
147 | /// specified point. | |||
148 | void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { | |||
149 | BB = TheBB; | |||
150 | InsertPt = IP; | |||
151 | if (IP != TheBB->end()) | |||
152 | SetCurrentDebugLocation(IP->getDebugLoc()); | |||
153 | } | |||
154 | ||||
155 | /// Set location information used by debugging information. | |||
156 | void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } | |||
157 | ||||
158 | /// Get location information used by debugging information. | |||
159 | const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } | |||
160 | ||||
161 | /// If this builder has a current debug location, set it on the | |||
162 | /// specified instruction. | |||
163 | void SetInstDebugLocation(Instruction *I) const { | |||
164 | if (CurDbgLocation) | |||
165 | I->setDebugLoc(CurDbgLocation); | |||
166 | } | |||
167 | ||||
168 | /// Get the return type of the current function that we're emitting | |||
169 | /// into. | |||
170 | Type *getCurrentFunctionReturnType() const; | |||
171 | ||||
172 | /// InsertPoint - A saved insertion point. | |||
173 | class InsertPoint { | |||
174 | BasicBlock *Block = nullptr; | |||
175 | BasicBlock::iterator Point; | |||
176 | ||||
177 | public: | |||
178 | /// Creates a new insertion point which doesn't point to anything. | |||
179 | InsertPoint() = default; | |||
180 | ||||
181 | /// Creates a new insertion point at the given location. | |||
182 | InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint) | |||
183 | : Block(InsertBlock), Point(InsertPoint) {} | |||
184 | ||||
185 | /// Returns true if this insert point is set. | |||
186 | bool isSet() const { return (Block != nullptr); } | |||
187 | ||||
188 | BasicBlock *getBlock() const { return Block; } | |||
189 | BasicBlock::iterator getPoint() const { return Point; } | |||
190 | }; | |||
191 | ||||
192 | /// Returns the current insert point. | |||
193 | InsertPoint saveIP() const { | |||
194 | return InsertPoint(GetInsertBlock(), GetInsertPoint()); | |||
195 | } | |||
196 | ||||
197 | /// Returns the current insert point, clearing it in the process. | |||
198 | InsertPoint saveAndClearIP() { | |||
199 | InsertPoint IP(GetInsertBlock(), GetInsertPoint()); | |||
200 | ClearInsertionPoint(); | |||
201 | return IP; | |||
202 | } | |||
203 | ||||
204 | /// Sets the current insert point to a previously-saved location. | |||
205 | void restoreIP(InsertPoint IP) { | |||
206 | if (IP.isSet()) | |||
207 | SetInsertPoint(IP.getBlock(), IP.getPoint()); | |||
208 | else | |||
209 | ClearInsertionPoint(); | |||
210 | } | |||
211 | ||||
212 | /// Get the floating point math metadata being used. | |||
213 | MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } | |||
214 | ||||
215 | /// Get the flags to be applied to created floating point ops | |||
216 | FastMathFlags getFastMathFlags() const { return FMF; } | |||
217 | ||||
218 | /// Clear the fast-math flags. | |||
219 | void clearFastMathFlags() { FMF.clear(); } | |||
220 | ||||
221 | /// Set the floating point math metadata to be used. | |||
222 | void setDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } | |||
223 | ||||
224 | /// Set the fast-math flags to be used with generated fp-math operators | |||
225 | void setFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } | |||
226 | ||||
227 | /// Enable/Disable use of constrained floating point math. When | |||
228 | /// enabled the CreateF<op>() calls instead create constrained | |||
229 | /// floating point intrinsic calls. Fast math flags are unaffected | |||
230 | /// by this setting. | |||
231 | void setIsFPConstrained(bool IsCon) { IsFPConstrained = IsCon; } | |||
232 | ||||
233 | /// Query for the use of constrained floating point math | |||
234 | bool getIsFPConstrained() { return IsFPConstrained; } | |||
235 | ||||
236 | /// Set the exception handling to be used with constrained floating point | |||
237 | void setDefaultConstrainedExcept(fp::ExceptionBehavior NewExcept) { | |||
238 | DefaultConstrainedExcept = NewExcept; | |||
239 | } | |||
240 | ||||
241 | /// Set the rounding mode handling to be used with constrained floating point | |||
242 | void setDefaultConstrainedRounding(fp::RoundingMode NewRounding) { | |||
243 | DefaultConstrainedRounding = NewRounding; | |||
244 | } | |||
245 | ||||
246 | /// Get the exception handling used with constrained floating point | |||
247 | fp::ExceptionBehavior getDefaultConstrainedExcept() { | |||
248 | return DefaultConstrainedExcept; | |||
249 | } | |||
250 | ||||
251 | /// Get the rounding mode handling used with constrained floating point | |||
252 | fp::RoundingMode getDefaultConstrainedRounding() { | |||
253 | return DefaultConstrainedRounding; | |||
254 | } | |||
255 | ||||
256 | void setConstrainedFPFunctionAttr() { | |||
257 | assert(BB && "Must have a basic block to set any function attributes!")((BB && "Must have a basic block to set any function attributes!" ) ? static_cast<void> (0) : __assert_fail ("BB && \"Must have a basic block to set any function attributes!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 257, __PRETTY_FUNCTION__)); | |||
258 | ||||
259 | Function *F = BB->getParent(); | |||
260 | if (!F->hasFnAttribute(Attribute::StrictFP)) { | |||
261 | F->addFnAttr(Attribute::StrictFP); | |||
262 | } | |||
263 | } | |||
264 | ||||
265 | void setConstrainedFPCallAttr(CallInst *I) { | |||
266 | if (!I->hasFnAttr(Attribute::StrictFP)) | |||
267 | I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP); | |||
268 | } | |||
269 | ||||
270 | //===--------------------------------------------------------------------===// | |||
271 | // RAII helpers. | |||
272 | //===--------------------------------------------------------------------===// | |||
273 | ||||
274 | // RAII object that stores the current insertion point and restores it | |||
275 | // when the object is destroyed. This includes the debug location. | |||
276 | class InsertPointGuard { | |||
277 | IRBuilderBase &Builder; | |||
278 | AssertingVH<BasicBlock> Block; | |||
279 | BasicBlock::iterator Point; | |||
280 | DebugLoc DbgLoc; | |||
281 | ||||
282 | public: | |||
283 | InsertPointGuard(IRBuilderBase &B) | |||
284 | : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()), | |||
285 | DbgLoc(B.getCurrentDebugLocation()) {} | |||
286 | ||||
287 | InsertPointGuard(const InsertPointGuard &) = delete; | |||
288 | InsertPointGuard &operator=(const InsertPointGuard &) = delete; | |||
289 | ||||
290 | ~InsertPointGuard() { | |||
291 | Builder.restoreIP(InsertPoint(Block, Point)); | |||
292 | Builder.SetCurrentDebugLocation(DbgLoc); | |||
293 | } | |||
294 | }; | |||
295 | ||||
296 | // RAII object that stores the current fast math settings and restores | |||
297 | // them when the object is destroyed. | |||
298 | class FastMathFlagGuard { | |||
299 | IRBuilderBase &Builder; | |||
300 | FastMathFlags FMF; | |||
301 | MDNode *FPMathTag; | |||
302 | ||||
303 | public: | |||
304 | FastMathFlagGuard(IRBuilderBase &B) | |||
305 | : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {} | |||
306 | ||||
307 | FastMathFlagGuard(const FastMathFlagGuard &) = delete; | |||
308 | FastMathFlagGuard &operator=(const FastMathFlagGuard &) = delete; | |||
309 | ||||
310 | ~FastMathFlagGuard() { | |||
311 | Builder.FMF = FMF; | |||
312 | Builder.DefaultFPMathTag = FPMathTag; | |||
313 | } | |||
314 | }; | |||
315 | ||||
316 | //===--------------------------------------------------------------------===// | |||
317 | // Miscellaneous creation methods. | |||
318 | //===--------------------------------------------------------------------===// | |||
319 | ||||
320 | /// Make a new global variable with initializer type i8* | |||
321 | /// | |||
322 | /// Make a new global variable with an initializer that has array of i8 type | |||
323 | /// filled in with the null terminated string value specified. The new global | |||
324 | /// variable will be marked mergable with any others of the same contents. If | |||
325 | /// Name is specified, it is the name of the global variable created. | |||
326 | GlobalVariable *CreateGlobalString(StringRef Str, const Twine &Name = "", | |||
327 | unsigned AddressSpace = 0); | |||
328 | ||||
329 | /// Get a constant value representing either true or false. | |||
330 | ConstantInt *getInt1(bool V) { | |||
331 | return ConstantInt::get(getInt1Ty(), V); | |||
332 | } | |||
333 | ||||
334 | /// Get the constant value for i1 true. | |||
335 | ConstantInt *getTrue() { | |||
336 | return ConstantInt::getTrue(Context); | |||
337 | } | |||
338 | ||||
339 | /// Get the constant value for i1 false. | |||
340 | ConstantInt *getFalse() { | |||
341 | return ConstantInt::getFalse(Context); | |||
342 | } | |||
343 | ||||
344 | /// Get a constant 8-bit value. | |||
345 | ConstantInt *getInt8(uint8_t C) { | |||
346 | return ConstantInt::get(getInt8Ty(), C); | |||
347 | } | |||
348 | ||||
349 | /// Get a constant 16-bit value. | |||
350 | ConstantInt *getInt16(uint16_t C) { | |||
351 | return ConstantInt::get(getInt16Ty(), C); | |||
352 | } | |||
353 | ||||
354 | /// Get a constant 32-bit value. | |||
355 | ConstantInt *getInt32(uint32_t C) { | |||
356 | return ConstantInt::get(getInt32Ty(), C); | |||
357 | } | |||
358 | ||||
359 | /// Get a constant 64-bit value. | |||
360 | ConstantInt *getInt64(uint64_t C) { | |||
361 | return ConstantInt::get(getInt64Ty(), C); | |||
362 | } | |||
363 | ||||
364 | /// Get a constant N-bit value, zero extended or truncated from | |||
365 | /// a 64-bit value. | |||
366 | ConstantInt *getIntN(unsigned N, uint64_t C) { | |||
367 | return ConstantInt::get(getIntNTy(N), C); | |||
368 | } | |||
369 | ||||
370 | /// Get a constant integer value. | |||
371 | ConstantInt *getInt(const APInt &AI) { | |||
372 | return ConstantInt::get(Context, AI); | |||
373 | } | |||
374 | ||||
375 | //===--------------------------------------------------------------------===// | |||
376 | // Type creation methods | |||
377 | //===--------------------------------------------------------------------===// | |||
378 | ||||
379 | /// Fetch the type representing a single bit | |||
380 | IntegerType *getInt1Ty() { | |||
381 | return Type::getInt1Ty(Context); | |||
382 | } | |||
383 | ||||
384 | /// Fetch the type representing an 8-bit integer. | |||
385 | IntegerType *getInt8Ty() { | |||
386 | return Type::getInt8Ty(Context); | |||
387 | } | |||
388 | ||||
389 | /// Fetch the type representing a 16-bit integer. | |||
390 | IntegerType *getInt16Ty() { | |||
391 | return Type::getInt16Ty(Context); | |||
392 | } | |||
393 | ||||
394 | /// Fetch the type representing a 32-bit integer. | |||
395 | IntegerType *getInt32Ty() { | |||
396 | return Type::getInt32Ty(Context); | |||
397 | } | |||
398 | ||||
399 | /// Fetch the type representing a 64-bit integer. | |||
400 | IntegerType *getInt64Ty() { | |||
401 | return Type::getInt64Ty(Context); | |||
402 | } | |||
403 | ||||
404 | /// Fetch the type representing a 128-bit integer. | |||
405 | IntegerType *getInt128Ty() { return Type::getInt128Ty(Context); } | |||
406 | ||||
407 | /// Fetch the type representing an N-bit integer. | |||
408 | IntegerType *getIntNTy(unsigned N) { | |||
409 | return Type::getIntNTy(Context, N); | |||
410 | } | |||
411 | ||||
412 | /// Fetch the type representing a 16-bit floating point value. | |||
413 | Type *getHalfTy() { | |||
414 | return Type::getHalfTy(Context); | |||
415 | } | |||
416 | ||||
417 | /// Fetch the type representing a 32-bit floating point value. | |||
418 | Type *getFloatTy() { | |||
419 | return Type::getFloatTy(Context); | |||
420 | } | |||
421 | ||||
422 | /// Fetch the type representing a 64-bit floating point value. | |||
423 | Type *getDoubleTy() { | |||
424 | return Type::getDoubleTy(Context); | |||
425 | } | |||
426 | ||||
427 | /// Fetch the type representing void. | |||
428 | Type *getVoidTy() { | |||
429 | return Type::getVoidTy(Context); | |||
430 | } | |||
431 | ||||
432 | /// Fetch the type representing a pointer to an 8-bit integer value. | |||
433 | PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { | |||
434 | return Type::getInt8PtrTy(Context, AddrSpace); | |||
435 | } | |||
436 | ||||
437 | /// Fetch the type representing a pointer to an integer value. | |||
438 | IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) { | |||
439 | return DL.getIntPtrType(Context, AddrSpace); | |||
440 | } | |||
441 | ||||
442 | //===--------------------------------------------------------------------===// | |||
443 | // Intrinsic creation methods | |||
444 | //===--------------------------------------------------------------------===// | |||
445 | ||||
446 | /// Create and insert a memset to the specified pointer and the | |||
447 | /// specified value. | |||
448 | /// | |||
449 | /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is | |||
450 | /// specified, it will be added to the instruction. Likewise with alias.scope | |||
451 | /// and noalias tags. | |||
452 | CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, | |||
453 | MaybeAlign Align, bool isVolatile = false, | |||
454 | MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, | |||
455 | MDNode *NoAliasTag = nullptr) { | |||
456 | return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, | |||
457 | TBAATag, ScopeTag, NoAliasTag); | |||
458 | } | |||
459 | ||||
460 | CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, MaybeAlign Align, | |||
461 | bool isVolatile = false, MDNode *TBAATag = nullptr, | |||
462 | MDNode *ScopeTag = nullptr, | |||
463 | MDNode *NoAliasTag = nullptr); | |||
464 | ||||
465 | /// Create and insert an element unordered-atomic memset of the region of | |||
466 | /// memory starting at the given pointer to the given value. | |||
467 | /// | |||
468 | /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is | |||
469 | /// specified, it will be added to the instruction. Likewise with alias.scope | |||
470 | /// and noalias tags. | |||
471 | /// FIXME: Remove this function once transition to Align is over. | |||
472 | /// Use the version that takes Align instead of this one. | |||
473 | LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment, uint32_t ElementSize , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
474 | CallInst *CreateElementUnorderedAtomicMemSet(CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment, uint32_t ElementSize , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
475 | Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment,CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment, uint32_t ElementSize , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
476 | uint32_t ElementSize, MDNode *TBAATag = nullptr,CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment, uint32_t ElementSize , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
477 | MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment, uint32_t ElementSize , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
478 | "Use the version that takes Align instead of this one")CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment, uint32_t ElementSize , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) { | |||
479 | return CreateElementUnorderedAtomicMemSet(Ptr, Val, getInt64(Size), | |||
480 | Align(Alignment), ElementSize, | |||
481 | TBAATag, ScopeTag, NoAliasTag); | |||
482 | } | |||
483 | ||||
484 | CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, | |||
485 | uint64_t Size, Align Alignment, | |||
486 | uint32_t ElementSize, | |||
487 | MDNode *TBAATag = nullptr, | |||
488 | MDNode *ScopeTag = nullptr, | |||
489 | MDNode *NoAliasTag = nullptr) { | |||
490 | return CreateElementUnorderedAtomicMemSet(Ptr, Val, getInt64(Size), | |||
491 | Align(Alignment), ElementSize, | |||
492 | TBAATag, ScopeTag, NoAliasTag); | |||
493 | } | |||
494 | ||||
495 | /// FIXME: Remove this function once transition to Align is over. | |||
496 | /// Use the version that takes Align instead of this one. | |||
497 | LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, Value *Size, unsigned Alignment, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
498 | CallInst *CreateElementUnorderedAtomicMemSet(CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, Value *Size, unsigned Alignment, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
499 | Value *Ptr, Value *Val, Value *Size, unsigned Alignment,CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, Value *Size, unsigned Alignment, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
500 | uint32_t ElementSize, MDNode *TBAATag = nullptr,CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, Value *Size, unsigned Alignment, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
501 | MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, Value *Size, unsigned Alignment, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) | |||
502 | "Use the version that takes Align instead of this one")CallInst *CreateElementUnorderedAtomicMemSet( Value *Ptr, Value *Val, Value *Size, unsigned Alignment, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes Align instead of this one" ))) { | |||
503 | return CreateElementUnorderedAtomicMemSet(Ptr, Val, Size, Align(Alignment), | |||
504 | ElementSize, TBAATag, ScopeTag, | |||
505 | NoAliasTag); | |||
506 | } | |||
507 | ||||
508 | CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, | |||
509 | Value *Size, Align Alignment, | |||
510 | uint32_t ElementSize, | |||
511 | MDNode *TBAATag = nullptr, | |||
512 | MDNode *ScopeTag = nullptr, | |||
513 | MDNode *NoAliasTag = nullptr); | |||
514 | ||||
515 | /// Create and insert a memcpy between the specified pointers. | |||
516 | /// | |||
517 | /// If the pointers aren't i8*, they will be converted. If a TBAA tag is | |||
518 | /// specified, it will be added to the instruction. Likewise with alias.scope | |||
519 | /// and noalias tags. | |||
520 | /// FIXME: Remove this function once transition to Align is over. | |||
521 | /// Use the version that takes MaybeAlign instead of this one. | |||
522 | LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
523 | CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
524 | unsigned SrcAlign, uint64_t Size,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
525 | bool isVolatile = false, MDNode *TBAATag = nullptr,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
526 | MDNode *TBAAStructTag = nullptr,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
527 | MDNode *ScopeTag = nullptr,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
528 | MDNode *NoAliasTag = nullptr),CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
529 | "Use the version that takes MaybeAlign instead")CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) { | |||
530 | return CreateMemCpy(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign), | |||
531 | getInt64(Size), isVolatile, TBAATag, TBAAStructTag, | |||
532 | ScopeTag, NoAliasTag); | |||
533 | } | |||
534 | ||||
535 | CallInst *CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, | |||
536 | MaybeAlign SrcAlign, uint64_t Size, | |||
537 | bool isVolatile = false, MDNode *TBAATag = nullptr, | |||
538 | MDNode *TBAAStructTag = nullptr, | |||
539 | MDNode *ScopeTag = nullptr, | |||
540 | MDNode *NoAliasTag = nullptr) { | |||
541 | return CreateMemCpy(Dst, DstAlign, Src, SrcAlign, getInt64(Size), | |||
542 | isVolatile, TBAATag, TBAAStructTag, ScopeTag, | |||
543 | NoAliasTag); | |||
544 | } | |||
545 | ||||
546 | /// FIXME: Remove this function once transition to Align is over. | |||
547 | /// Use the version that takes MaybeAlign instead of this one. | |||
548 | LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
549 | CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
550 | unsigned SrcAlign, Value *Size,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
551 | bool isVolatile = false, MDNode *TBAATag = nullptr,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
552 | MDNode *TBAAStructTag = nullptr,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
553 | MDNode *ScopeTag = nullptr,CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
554 | MDNode *NoAliasTag = nullptr),CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )) | |||
555 | "Use the version that takes MaybeAlign instead")CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value * Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__ ((deprecated("Use the version that takes MaybeAlign instead") )); | |||
556 | CallInst *CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, | |||
557 | MaybeAlign SrcAlign, Value *Size, | |||
558 | bool isVolatile = false, MDNode *TBAATag = nullptr, | |||
559 | MDNode *TBAAStructTag = nullptr, | |||
560 | MDNode *ScopeTag = nullptr, | |||
561 | MDNode *NoAliasTag = nullptr); | |||
562 | ||||
563 | /// Create and insert an element unordered-atomic memcpy between the | |||
564 | /// specified pointers. | |||
565 | /// | |||
566 | /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, respectively. | |||
567 | /// | |||
568 | /// If the pointers aren't i8*, they will be converted. If a TBAA tag is | |||
569 | /// specified, it will be added to the instruction. Likewise with alias.scope | |||
570 | /// and noalias tags. | |||
571 | CallInst *CreateElementUnorderedAtomicMemCpy( | |||
572 | Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, | |||
573 | uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, | |||
574 | MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, | |||
575 | MDNode *NoAliasTag = nullptr) { | |||
576 | return CreateElementUnorderedAtomicMemCpy( | |||
577 | Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, | |||
578 | TBAAStructTag, ScopeTag, NoAliasTag); | |||
579 | } | |||
580 | ||||
581 | CallInst *CreateElementUnorderedAtomicMemCpy( | |||
582 | Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, | |||
583 | uint32_t ElementSize, MDNode *TBAATag = nullptr, | |||
584 | MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, | |||
585 | MDNode *NoAliasTag = nullptr); | |||
586 | ||||
587 | /// Create and insert a memmove between the specified | |||
588 | /// pointers. | |||
589 | /// | |||
590 | /// If the pointers aren't i8*, they will be converted. If a TBAA tag is | |||
591 | /// specified, it will be added to the instruction. Likewise with alias.scope | |||
592 | /// and noalias tags. | |||
593 | /// FIXME: Remove this function once transition to Align is over. | |||
594 | /// Use the version that takes MaybeAlign instead of this one. | |||
595 | LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
596 | CallInst *CreateMemMove(CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
597 | Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
598 | uint64_t Size, bool isVolatile = false, MDNode *TBAATag = nullptr,CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
599 | MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
600 | "Use the version that takes MaybeAlign")CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) { | |||
601 | return CreateMemMove(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign), | |||
602 | getInt64(Size), isVolatile, TBAATag, ScopeTag, | |||
603 | NoAliasTag); | |||
604 | } | |||
605 | CallInst *CreateMemMove(Value *Dst, MaybeAlign DstAlign, Value *Src, | |||
606 | MaybeAlign SrcAlign, uint64_t Size, | |||
607 | bool isVolatile = false, MDNode *TBAATag = nullptr, | |||
608 | MDNode *ScopeTag = nullptr, | |||
609 | MDNode *NoAliasTag = nullptr) { | |||
610 | return CreateMemMove(Dst, DstAlign, Src, SrcAlign, getInt64(Size), | |||
611 | isVolatile, TBAATag, ScopeTag, NoAliasTag); | |||
612 | } | |||
613 | /// FIXME: Remove this function once transition to Align is over. | |||
614 | /// Use the version that takes MaybeAlign instead of this one. | |||
615 | LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
616 | CallInst *CreateMemMove(CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
617 | Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
618 | Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr,CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
619 | MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) | |||
620 | "Use the version that takes MaybeAlign")CallInst *CreateMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false , MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) __attribute__((deprecated("Use the version that takes MaybeAlign" ))) { | |||
621 | return CreateMemMove(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign), | |||
622 | Size, isVolatile, TBAATag, ScopeTag, NoAliasTag); | |||
623 | } | |||
624 | CallInst *CreateMemMove(Value *Dst, MaybeAlign DstAlign, Value *Src, | |||
625 | MaybeAlign SrcAlign, Value *Size, | |||
626 | bool isVolatile = false, MDNode *TBAATag = nullptr, | |||
627 | MDNode *ScopeTag = nullptr, | |||
628 | MDNode *NoAliasTag = nullptr); | |||
629 | ||||
630 | /// \brief Create and insert an element unordered-atomic memmove between the | |||
631 | /// specified pointers. | |||
632 | /// | |||
633 | /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, | |||
634 | /// respectively. | |||
635 | /// | |||
636 | /// If the pointers aren't i8*, they will be converted. If a TBAA tag is | |||
637 | /// specified, it will be added to the instruction. Likewise with alias.scope | |||
638 | /// and noalias tags. | |||
639 | CallInst *CreateElementUnorderedAtomicMemMove( | |||
640 | Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, | |||
641 | uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, | |||
642 | MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, | |||
643 | MDNode *NoAliasTag = nullptr) { | |||
644 | return CreateElementUnorderedAtomicMemMove( | |||
645 | Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, | |||
646 | TBAAStructTag, ScopeTag, NoAliasTag); | |||
647 | } | |||
648 | ||||
649 | CallInst *CreateElementUnorderedAtomicMemMove( | |||
650 | Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, | |||
651 | uint32_t ElementSize, MDNode *TBAATag = nullptr, | |||
652 | MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, | |||
653 | MDNode *NoAliasTag = nullptr); | |||
654 | ||||
655 | /// Create a vector fadd reduction intrinsic of the source vector. | |||
656 | /// The first parameter is a scalar accumulator value for ordered reductions. | |||
657 | CallInst *CreateFAddReduce(Value *Acc, Value *Src); | |||
658 | ||||
659 | /// Create a vector fmul reduction intrinsic of the source vector. | |||
660 | /// The first parameter is a scalar accumulator value for ordered reductions. | |||
661 | CallInst *CreateFMulReduce(Value *Acc, Value *Src); | |||
662 | ||||
663 | /// Create a vector int add reduction intrinsic of the source vector. | |||
664 | CallInst *CreateAddReduce(Value *Src); | |||
665 | ||||
666 | /// Create a vector int mul reduction intrinsic of the source vector. | |||
667 | CallInst *CreateMulReduce(Value *Src); | |||
668 | ||||
669 | /// Create a vector int AND reduction intrinsic of the source vector. | |||
670 | CallInst *CreateAndReduce(Value *Src); | |||
671 | ||||
672 | /// Create a vector int OR reduction intrinsic of the source vector. | |||
673 | CallInst *CreateOrReduce(Value *Src); | |||
674 | ||||
675 | /// Create a vector int XOR reduction intrinsic of the source vector. | |||
676 | CallInst *CreateXorReduce(Value *Src); | |||
677 | ||||
678 | /// Create a vector integer max reduction intrinsic of the source | |||
679 | /// vector. | |||
680 | CallInst *CreateIntMaxReduce(Value *Src, bool IsSigned = false); | |||
681 | ||||
682 | /// Create a vector integer min reduction intrinsic of the source | |||
683 | /// vector. | |||
684 | CallInst *CreateIntMinReduce(Value *Src, bool IsSigned = false); | |||
685 | ||||
686 | /// Create a vector float max reduction intrinsic of the source | |||
687 | /// vector. | |||
688 | CallInst *CreateFPMaxReduce(Value *Src, bool NoNaN = false); | |||
689 | ||||
690 | /// Create a vector float min reduction intrinsic of the source | |||
691 | /// vector. | |||
692 | CallInst *CreateFPMinReduce(Value *Src, bool NoNaN = false); | |||
693 | ||||
694 | /// Create a lifetime.start intrinsic. | |||
695 | /// | |||
696 | /// If the pointer isn't i8* it will be converted. | |||
697 | CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = nullptr); | |||
698 | ||||
699 | /// Create a lifetime.end intrinsic. | |||
700 | /// | |||
701 | /// If the pointer isn't i8* it will be converted. | |||
702 | CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = nullptr); | |||
703 | ||||
704 | /// Create a call to invariant.start intrinsic. | |||
705 | /// | |||
706 | /// If the pointer isn't i8* it will be converted. | |||
707 | CallInst *CreateInvariantStart(Value *Ptr, ConstantInt *Size = nullptr); | |||
708 | ||||
709 | /// Create a call to Masked Load intrinsic | |||
710 | CallInst *CreateMaskedLoad(Value *Ptr, unsigned Align, Value *Mask, | |||
711 | Value *PassThru = nullptr, const Twine &Name = ""); | |||
712 | ||||
713 | /// Create a call to Masked Store intrinsic | |||
714 | CallInst *CreateMaskedStore(Value *Val, Value *Ptr, unsigned Align, | |||
715 | Value *Mask); | |||
716 | ||||
717 | /// Create a call to Masked Gather intrinsic | |||
718 | CallInst *CreateMaskedGather(Value *Ptrs, unsigned Align, | |||
719 | Value *Mask = nullptr, | |||
720 | Value *PassThru = nullptr, | |||
721 | const Twine& Name = ""); | |||
722 | ||||
723 | /// Create a call to Masked Scatter intrinsic | |||
724 | CallInst *CreateMaskedScatter(Value *Val, Value *Ptrs, unsigned Align, | |||
725 | Value *Mask = nullptr); | |||
726 | ||||
727 | /// Create an assume intrinsic call that allows the optimizer to | |||
728 | /// assume that the provided condition will be true. | |||
729 | CallInst *CreateAssumption(Value *Cond); | |||
730 | ||||
731 | /// Create a call to the experimental.gc.statepoint intrinsic to | |||
732 | /// start a new statepoint sequence. | |||
733 | CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, | |||
734 | Value *ActualCallee, | |||
735 | ArrayRef<Value *> CallArgs, | |||
736 | ArrayRef<Value *> DeoptArgs, | |||
737 | ArrayRef<Value *> GCArgs, | |||
738 | const Twine &Name = ""); | |||
739 | ||||
740 | /// Create a call to the experimental.gc.statepoint intrinsic to | |||
741 | /// start a new statepoint sequence. | |||
742 | CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, | |||
743 | Value *ActualCallee, uint32_t Flags, | |||
744 | ArrayRef<Use> CallArgs, | |||
745 | ArrayRef<Use> TransitionArgs, | |||
746 | ArrayRef<Use> DeoptArgs, | |||
747 | ArrayRef<Value *> GCArgs, | |||
748 | const Twine &Name = ""); | |||
749 | ||||
750 | /// Conveninence function for the common case when CallArgs are filled | |||
751 | /// in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be | |||
752 | /// .get()'ed to get the Value pointer. | |||
753 | CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, | |||
754 | Value *ActualCallee, ArrayRef<Use> CallArgs, | |||
755 | ArrayRef<Value *> DeoptArgs, | |||
756 | ArrayRef<Value *> GCArgs, | |||
757 | const Twine &Name = ""); | |||
758 | ||||
759 | /// Create an invoke to the experimental.gc.statepoint intrinsic to | |||
760 | /// start a new statepoint sequence. | |||
761 | InvokeInst * | |||
762 | CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, | |||
763 | Value *ActualInvokee, BasicBlock *NormalDest, | |||
764 | BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs, | |||
765 | ArrayRef<Value *> DeoptArgs, | |||
766 | ArrayRef<Value *> GCArgs, const Twine &Name = ""); | |||
767 | ||||
768 | /// Create an invoke to the experimental.gc.statepoint intrinsic to | |||
769 | /// start a new statepoint sequence. | |||
770 | InvokeInst *CreateGCStatepointInvoke( | |||
771 | uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, | |||
772 | BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, | |||
773 | ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs, | |||
774 | ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, | |||
775 | const Twine &Name = ""); | |||
776 | ||||
777 | // Convenience function for the common case when CallArgs are filled in using | |||
778 | // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to | |||
779 | // get the Value *. | |||
780 | InvokeInst * | |||
781 | CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, | |||
782 | Value *ActualInvokee, BasicBlock *NormalDest, | |||
783 | BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs, | |||
784 | ArrayRef<Value *> DeoptArgs, | |||
785 | ArrayRef<Value *> GCArgs, const Twine &Name = ""); | |||
786 | ||||
787 | /// Create a call to the experimental.gc.result intrinsic to extract | |||
788 | /// the result from a call wrapped in a statepoint. | |||
789 | CallInst *CreateGCResult(Instruction *Statepoint, | |||
790 | Type *ResultType, | |||
791 | const Twine &Name = ""); | |||
792 | ||||
793 | /// Create a call to the experimental.gc.relocate intrinsics to | |||
794 | /// project the relocated value of one pointer from the statepoint. | |||
795 | CallInst *CreateGCRelocate(Instruction *Statepoint, | |||
796 | int BaseOffset, | |||
797 | int DerivedOffset, | |||
798 | Type *ResultType, | |||
799 | const Twine &Name = ""); | |||
800 | ||||
801 | /// Create a call to intrinsic \p ID with 1 operand which is mangled on its | |||
802 | /// type. | |||
803 | CallInst *CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, | |||
804 | Instruction *FMFSource = nullptr, | |||
805 | const Twine &Name = ""); | |||
806 | ||||
807 | /// Create a call to intrinsic \p ID with 2 operands which is mangled on the | |||
808 | /// first type. | |||
809 | CallInst *CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, | |||
810 | Instruction *FMFSource = nullptr, | |||
811 | const Twine &Name = ""); | |||
812 | ||||
813 | /// Create a call to intrinsic \p ID with \p args, mangled using \p Types. If | |||
814 | /// \p FMFSource is provided, copy fast-math-flags from that instruction to | |||
815 | /// the intrinsic. | |||
816 | CallInst *CreateIntrinsic(Intrinsic::ID ID, ArrayRef<Type *> Types, | |||
817 | ArrayRef<Value *> Args, | |||
818 | Instruction *FMFSource = nullptr, | |||
819 | const Twine &Name = ""); | |||
820 | ||||
821 | /// Create call to the minnum intrinsic. | |||
822 | CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
823 | return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, nullptr, Name); | |||
824 | } | |||
825 | ||||
826 | /// Create call to the maxnum intrinsic. | |||
827 | CallInst *CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
828 | return CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS, nullptr, Name); | |||
829 | } | |||
830 | ||||
831 | /// Create call to the minimum intrinsic. | |||
832 | CallInst *CreateMinimum(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
833 | return CreateBinaryIntrinsic(Intrinsic::minimum, LHS, RHS, nullptr, Name); | |||
834 | } | |||
835 | ||||
836 | /// Create call to the maximum intrinsic. | |||
837 | CallInst *CreateMaximum(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
838 | return CreateBinaryIntrinsic(Intrinsic::maximum, LHS, RHS, nullptr, Name); | |||
839 | } | |||
840 | ||||
841 | private: | |||
842 | /// Create a call to a masked intrinsic with given Id. | |||
843 | CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef<Value *> Ops, | |||
844 | ArrayRef<Type *> OverloadedTypes, | |||
845 | const Twine &Name = ""); | |||
846 | ||||
847 | Value *getCastedInt8PtrValue(Value *Ptr); | |||
848 | }; | |||
849 | ||||
850 | /// This provides a uniform API for creating instructions and inserting | |||
851 | /// them into a basic block: either at the end of a BasicBlock, or at a specific | |||
852 | /// iterator location in a block. | |||
853 | /// | |||
854 | /// Note that the builder does not expose the full generality of LLVM | |||
855 | /// instructions. For access to extra instruction properties, use the mutators | |||
856 | /// (e.g. setVolatile) on the instructions after they have been | |||
857 | /// created. Convenience state exists to specify fast-math flags and fp-math | |||
858 | /// tags. | |||
859 | /// | |||
860 | /// The first template argument specifies a class to use for creating constants. | |||
861 | /// This defaults to creating minimally folded constants. The second template | |||
862 | /// argument allows clients to specify custom insertion hooks that are called on | |||
863 | /// every newly created insertion. | |||
864 | template <typename T = ConstantFolder, | |||
865 | typename Inserter = IRBuilderDefaultInserter> | |||
866 | class IRBuilder : public IRBuilderBase, public Inserter { | |||
867 | T Folder; | |||
868 | ||||
869 | public: | |||
870 | IRBuilder(LLVMContext &C, const T &F, Inserter I = Inserter(), | |||
871 | MDNode *FPMathTag = nullptr, | |||
872 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
873 | : IRBuilderBase(C, FPMathTag, OpBundles), Inserter(std::move(I)), | |||
874 | Folder(F) {} | |||
875 | ||||
876 | explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr, | |||
877 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
878 | : IRBuilderBase(C, FPMathTag, OpBundles) {} | |||
879 | ||||
880 | explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = nullptr, | |||
881 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
882 | : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) { | |||
883 | SetInsertPoint(TheBB); | |||
884 | } | |||
885 | ||||
886 | explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr, | |||
887 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
888 | : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) { | |||
889 | SetInsertPoint(TheBB); | |||
890 | } | |||
891 | ||||
892 | explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr, | |||
893 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
894 | : IRBuilderBase(IP->getContext(), FPMathTag, OpBundles) { | |||
895 | SetInsertPoint(IP); | |||
896 | } | |||
897 | ||||
898 | IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T &F, | |||
899 | MDNode *FPMathTag = nullptr, | |||
900 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
901 | : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) { | |||
902 | SetInsertPoint(TheBB, IP); | |||
903 | } | |||
904 | ||||
905 | IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, | |||
906 | MDNode *FPMathTag = nullptr, | |||
907 | ArrayRef<OperandBundleDef> OpBundles = None) | |||
908 | : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) { | |||
909 | SetInsertPoint(TheBB, IP); | |||
910 | } | |||
911 | ||||
912 | /// Get the constant folder being used. | |||
913 | const T &getFolder() { return Folder; } | |||
914 | ||||
915 | /// Insert and return the specified instruction. | |||
916 | template<typename InstTy> | |||
917 | InstTy *Insert(InstTy *I, const Twine &Name = "") const { | |||
918 | this->InsertHelper(I, Name, BB, InsertPt); | |||
919 | this->SetInstDebugLocation(I); | |||
920 | return I; | |||
921 | } | |||
922 | ||||
923 | /// No-op overload to handle constants. | |||
924 | Constant *Insert(Constant *C, const Twine& = "") const { | |||
925 | return C; | |||
926 | } | |||
927 | ||||
928 | //===--------------------------------------------------------------------===// | |||
929 | // Instruction creation methods: Terminators | |||
930 | //===--------------------------------------------------------------------===// | |||
931 | ||||
932 | private: | |||
933 | /// Helper to add branch weight and unpredictable metadata onto an | |||
934 | /// instruction. | |||
935 | /// \returns The annotated instruction. | |||
936 | template <typename InstTy> | |||
937 | InstTy *addBranchMetadata(InstTy *I, MDNode *Weights, MDNode *Unpredictable) { | |||
938 | if (Weights) | |||
939 | I->setMetadata(LLVMContext::MD_prof, Weights); | |||
940 | if (Unpredictable) | |||
941 | I->setMetadata(LLVMContext::MD_unpredictable, Unpredictable); | |||
942 | return I; | |||
943 | } | |||
944 | ||||
945 | public: | |||
946 | /// Create a 'ret void' instruction. | |||
947 | ReturnInst *CreateRetVoid() { | |||
948 | return Insert(ReturnInst::Create(Context)); | |||
949 | } | |||
950 | ||||
951 | /// Create a 'ret <val>' instruction. | |||
952 | ReturnInst *CreateRet(Value *V) { | |||
953 | return Insert(ReturnInst::Create(Context, V)); | |||
954 | } | |||
955 | ||||
956 | /// Create a sequence of N insertvalue instructions, | |||
957 | /// with one Value from the retVals array each, that build a aggregate | |||
958 | /// return value one value at a time, and a ret instruction to return | |||
959 | /// the resulting aggregate value. | |||
960 | /// | |||
961 | /// This is a convenience function for code that uses aggregate return values | |||
962 | /// as a vehicle for having multiple return values. | |||
963 | ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { | |||
964 | Value *V = UndefValue::get(getCurrentFunctionReturnType()); | |||
965 | for (unsigned i = 0; i != N; ++i) | |||
966 | V = CreateInsertValue(V, retVals[i], i, "mrv"); | |||
967 | return Insert(ReturnInst::Create(Context, V)); | |||
968 | } | |||
969 | ||||
970 | /// Create an unconditional 'br label X' instruction. | |||
971 | BranchInst *CreateBr(BasicBlock *Dest) { | |||
972 | return Insert(BranchInst::Create(Dest)); | |||
973 | } | |||
974 | ||||
975 | /// Create a conditional 'br Cond, TrueDest, FalseDest' | |||
976 | /// instruction. | |||
977 | BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, | |||
978 | MDNode *BranchWeights = nullptr, | |||
979 | MDNode *Unpredictable = nullptr) { | |||
980 | return Insert(addBranchMetadata(BranchInst::Create(True, False, Cond), | |||
981 | BranchWeights, Unpredictable)); | |||
982 | } | |||
983 | ||||
984 | /// Create a conditional 'br Cond, TrueDest, FalseDest' | |||
985 | /// instruction. Copy branch meta data if available. | |||
986 | BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, | |||
987 | Instruction *MDSrc) { | |||
988 | BranchInst *Br = BranchInst::Create(True, False, Cond); | |||
989 | if (MDSrc) { | |||
990 | unsigned WL[4] = {LLVMContext::MD_prof, LLVMContext::MD_unpredictable, | |||
991 | LLVMContext::MD_make_implicit, LLVMContext::MD_dbg}; | |||
992 | Br->copyMetadata(*MDSrc, makeArrayRef(&WL[0], 4)); | |||
993 | } | |||
994 | return Insert(Br); | |||
995 | } | |||
996 | ||||
997 | /// Create a switch instruction with the specified value, default dest, | |||
998 | /// and with a hint for the number of cases that will be added (for efficient | |||
999 | /// allocation). | |||
1000 | SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, | |||
1001 | MDNode *BranchWeights = nullptr, | |||
1002 | MDNode *Unpredictable = nullptr) { | |||
1003 | return Insert(addBranchMetadata(SwitchInst::Create(V, Dest, NumCases), | |||
1004 | BranchWeights, Unpredictable)); | |||
1005 | } | |||
1006 | ||||
1007 | /// Create an indirect branch instruction with the specified address | |||
1008 | /// operand, with an optional hint for the number of destinations that will be | |||
1009 | /// added (for efficient allocation). | |||
1010 | IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { | |||
1011 | return Insert(IndirectBrInst::Create(Addr, NumDests)); | |||
1012 | } | |||
1013 | ||||
1014 | /// Create an invoke instruction. | |||
1015 | InvokeInst *CreateInvoke(FunctionType *Ty, Value *Callee, | |||
1016 | BasicBlock *NormalDest, BasicBlock *UnwindDest, | |||
1017 | ArrayRef<Value *> Args, | |||
1018 | ArrayRef<OperandBundleDef> OpBundles, | |||
1019 | const Twine &Name = "") { | |||
1020 | return Insert( | |||
1021 | InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args, OpBundles), | |||
1022 | Name); | |||
1023 | } | |||
1024 | InvokeInst *CreateInvoke(FunctionType *Ty, Value *Callee, | |||
1025 | BasicBlock *NormalDest, BasicBlock *UnwindDest, | |||
1026 | ArrayRef<Value *> Args = None, | |||
1027 | const Twine &Name = "") { | |||
1028 | return Insert(InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args), | |||
1029 | Name); | |||
1030 | } | |||
1031 | ||||
1032 | InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest, | |||
1033 | BasicBlock *UnwindDest, ArrayRef<Value *> Args, | |||
1034 | ArrayRef<OperandBundleDef> OpBundles, | |||
1035 | const Twine &Name = "") { | |||
1036 | return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(), | |||
1037 | NormalDest, UnwindDest, Args, OpBundles, Name); | |||
1038 | } | |||
1039 | ||||
1040 | InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest, | |||
1041 | BasicBlock *UnwindDest, | |||
1042 | ArrayRef<Value *> Args = None, | |||
1043 | const Twine &Name = "") { | |||
1044 | return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(), | |||
1045 | NormalDest, UnwindDest, Args, Name); | |||
1046 | } | |||
1047 | ||||
1048 | // Deprecated [opaque pointer types] | |||
1049 | InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, | |||
1050 | BasicBlock *UnwindDest, ArrayRef<Value *> Args, | |||
1051 | ArrayRef<OperandBundleDef> OpBundles, | |||
1052 | const Twine &Name = "") { | |||
1053 | return CreateInvoke( | |||
1054 | cast<FunctionType>( | |||
1055 | cast<PointerType>(Callee->getType())->getElementType()), | |||
1056 | Callee, NormalDest, UnwindDest, Args, OpBundles, Name); | |||
1057 | } | |||
1058 | ||||
1059 | // Deprecated [opaque pointer types] | |||
1060 | InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, | |||
1061 | BasicBlock *UnwindDest, | |||
1062 | ArrayRef<Value *> Args = None, | |||
1063 | const Twine &Name = "") { | |||
1064 | return CreateInvoke( | |||
1065 | cast<FunctionType>( | |||
1066 | cast<PointerType>(Callee->getType())->getElementType()), | |||
1067 | Callee, NormalDest, UnwindDest, Args, Name); | |||
1068 | } | |||
1069 | ||||
1070 | /// \brief Create a callbr instruction. | |||
1071 | CallBrInst *CreateCallBr(FunctionType *Ty, Value *Callee, | |||
1072 | BasicBlock *DefaultDest, | |||
1073 | ArrayRef<BasicBlock *> IndirectDests, | |||
1074 | ArrayRef<Value *> Args = None, | |||
1075 | const Twine &Name = "") { | |||
1076 | return Insert(CallBrInst::Create(Ty, Callee, DefaultDest, IndirectDests, | |||
1077 | Args), Name); | |||
1078 | } | |||
1079 | CallBrInst *CreateCallBr(FunctionType *Ty, Value *Callee, | |||
1080 | BasicBlock *DefaultDest, | |||
1081 | ArrayRef<BasicBlock *> IndirectDests, | |||
1082 | ArrayRef<Value *> Args, | |||
1083 | ArrayRef<OperandBundleDef> OpBundles, | |||
1084 | const Twine &Name = "") { | |||
1085 | return Insert( | |||
1086 | CallBrInst::Create(Ty, Callee, DefaultDest, IndirectDests, Args, | |||
1087 | OpBundles), Name); | |||
1088 | } | |||
1089 | ||||
1090 | CallBrInst *CreateCallBr(FunctionCallee Callee, BasicBlock *DefaultDest, | |||
1091 | ArrayRef<BasicBlock *> IndirectDests, | |||
1092 | ArrayRef<Value *> Args = None, | |||
1093 | const Twine &Name = "") { | |||
1094 | return CreateCallBr(Callee.getFunctionType(), Callee.getCallee(), | |||
1095 | DefaultDest, IndirectDests, Args, Name); | |||
1096 | } | |||
1097 | CallBrInst *CreateCallBr(FunctionCallee Callee, BasicBlock *DefaultDest, | |||
1098 | ArrayRef<BasicBlock *> IndirectDests, | |||
1099 | ArrayRef<Value *> Args, | |||
1100 | ArrayRef<OperandBundleDef> OpBundles, | |||
1101 | const Twine &Name = "") { | |||
1102 | return CreateCallBr(Callee.getFunctionType(), Callee.getCallee(), | |||
1103 | DefaultDest, IndirectDests, Args, Name); | |||
1104 | } | |||
1105 | ||||
1106 | ResumeInst *CreateResume(Value *Exn) { | |||
1107 | return Insert(ResumeInst::Create(Exn)); | |||
1108 | } | |||
1109 | ||||
1110 | CleanupReturnInst *CreateCleanupRet(CleanupPadInst *CleanupPad, | |||
1111 | BasicBlock *UnwindBB = nullptr) { | |||
1112 | return Insert(CleanupReturnInst::Create(CleanupPad, UnwindBB)); | |||
1113 | } | |||
1114 | ||||
1115 | CatchSwitchInst *CreateCatchSwitch(Value *ParentPad, BasicBlock *UnwindBB, | |||
1116 | unsigned NumHandlers, | |||
1117 | const Twine &Name = "") { | |||
1118 | return Insert(CatchSwitchInst::Create(ParentPad, UnwindBB, NumHandlers), | |||
1119 | Name); | |||
1120 | } | |||
1121 | ||||
1122 | CatchPadInst *CreateCatchPad(Value *ParentPad, ArrayRef<Value *> Args, | |||
1123 | const Twine &Name = "") { | |||
1124 | return Insert(CatchPadInst::Create(ParentPad, Args), Name); | |||
1125 | } | |||
1126 | ||||
1127 | CleanupPadInst *CreateCleanupPad(Value *ParentPad, | |||
1128 | ArrayRef<Value *> Args = None, | |||
1129 | const Twine &Name = "") { | |||
1130 | return Insert(CleanupPadInst::Create(ParentPad, Args), Name); | |||
1131 | } | |||
1132 | ||||
1133 | CatchReturnInst *CreateCatchRet(CatchPadInst *CatchPad, BasicBlock *BB) { | |||
1134 | return Insert(CatchReturnInst::Create(CatchPad, BB)); | |||
1135 | } | |||
1136 | ||||
1137 | UnreachableInst *CreateUnreachable() { | |||
1138 | return Insert(new UnreachableInst(Context)); | |||
1139 | } | |||
1140 | ||||
1141 | //===--------------------------------------------------------------------===// | |||
1142 | // Instruction creation methods: Binary Operators | |||
1143 | //===--------------------------------------------------------------------===// | |||
1144 | private: | |||
1145 | BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc, | |||
1146 | Value *LHS, Value *RHS, | |||
1147 | const Twine &Name, | |||
1148 | bool HasNUW, bool HasNSW) { | |||
1149 | BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); | |||
1150 | if (HasNUW) BO->setHasNoUnsignedWrap(); | |||
1151 | if (HasNSW) BO->setHasNoSignedWrap(); | |||
1152 | return BO; | |||
1153 | } | |||
1154 | ||||
1155 | Instruction *setFPAttrs(Instruction *I, MDNode *FPMD, | |||
1156 | FastMathFlags FMF) const { | |||
1157 | if (!FPMD) | |||
1158 | FPMD = DefaultFPMathTag; | |||
1159 | if (FPMD) | |||
1160 | I->setMetadata(LLVMContext::MD_fpmath, FPMD); | |||
1161 | I->setFastMathFlags(FMF); | |||
1162 | return I; | |||
1163 | } | |||
1164 | ||||
1165 | Value *foldConstant(Instruction::BinaryOps Opc, Value *L, | |||
1166 | Value *R, const Twine &Name) const { | |||
1167 | auto *LC = dyn_cast<Constant>(L); | |||
1168 | auto *RC = dyn_cast<Constant>(R); | |||
1169 | return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr; | |||
1170 | } | |||
1171 | ||||
1172 | Value *getConstrainedFPRounding(Optional<fp::RoundingMode> Rounding) { | |||
1173 | fp::RoundingMode UseRounding = DefaultConstrainedRounding; | |||
1174 | ||||
1175 | if (Rounding.hasValue()) | |||
1176 | UseRounding = Rounding.getValue(); | |||
1177 | ||||
1178 | Optional<StringRef> RoundingStr = RoundingModeToStr(UseRounding); | |||
1179 | assert(RoundingStr.hasValue() && "Garbage strict rounding mode!")((RoundingStr.hasValue() && "Garbage strict rounding mode!" ) ? static_cast<void> (0) : __assert_fail ("RoundingStr.hasValue() && \"Garbage strict rounding mode!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1179, __PRETTY_FUNCTION__)); | |||
1180 | auto *RoundingMDS = MDString::get(Context, RoundingStr.getValue()); | |||
1181 | ||||
1182 | return MetadataAsValue::get(Context, RoundingMDS); | |||
1183 | } | |||
1184 | ||||
1185 | Value *getConstrainedFPExcept(Optional<fp::ExceptionBehavior> Except) { | |||
1186 | fp::ExceptionBehavior UseExcept = DefaultConstrainedExcept; | |||
1187 | ||||
1188 | if (Except.hasValue()) | |||
1189 | UseExcept = Except.getValue(); | |||
1190 | ||||
1191 | Optional<StringRef> ExceptStr = ExceptionBehaviorToStr(UseExcept); | |||
1192 | assert(ExceptStr.hasValue() && "Garbage strict exception behavior!")((ExceptStr.hasValue() && "Garbage strict exception behavior!" ) ? static_cast<void> (0) : __assert_fail ("ExceptStr.hasValue() && \"Garbage strict exception behavior!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1192, __PRETTY_FUNCTION__)); | |||
1193 | auto *ExceptMDS = MDString::get(Context, ExceptStr.getValue()); | |||
1194 | ||||
1195 | return MetadataAsValue::get(Context, ExceptMDS); | |||
1196 | } | |||
1197 | ||||
1198 | public: | |||
1199 | Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1200 | bool HasNUW = false, bool HasNSW = false) { | |||
1201 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1202 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1203 | return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name); | |||
1204 | return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name, | |||
1205 | HasNUW, HasNSW); | |||
1206 | } | |||
1207 | ||||
1208 | Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1209 | return CreateAdd(LHS, RHS, Name, false, true); | |||
1210 | } | |||
1211 | ||||
1212 | Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1213 | return CreateAdd(LHS, RHS, Name, true, false); | |||
1214 | } | |||
1215 | ||||
1216 | Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1217 | bool HasNUW = false, bool HasNSW = false) { | |||
1218 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1219 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1220 | return Insert(Folder.CreateSub(LC, RC, HasNUW, HasNSW), Name); | |||
1221 | return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name, | |||
1222 | HasNUW, HasNSW); | |||
1223 | } | |||
1224 | ||||
1225 | Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1226 | return CreateSub(LHS, RHS, Name, false, true); | |||
1227 | } | |||
1228 | ||||
1229 | Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1230 | return CreateSub(LHS, RHS, Name, true, false); | |||
1231 | } | |||
1232 | ||||
1233 | Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1234 | bool HasNUW = false, bool HasNSW = false) { | |||
1235 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1236 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1237 | return Insert(Folder.CreateMul(LC, RC, HasNUW, HasNSW), Name); | |||
1238 | return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name, | |||
1239 | HasNUW, HasNSW); | |||
1240 | } | |||
1241 | ||||
1242 | Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1243 | return CreateMul(LHS, RHS, Name, false, true); | |||
1244 | } | |||
1245 | ||||
1246 | Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1247 | return CreateMul(LHS, RHS, Name, true, false); | |||
1248 | } | |||
1249 | ||||
1250 | Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1251 | bool isExact = false) { | |||
1252 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1253 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1254 | return Insert(Folder.CreateUDiv(LC, RC, isExact), Name); | |||
1255 | if (!isExact) | |||
1256 | return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); | |||
1257 | return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name); | |||
1258 | } | |||
1259 | ||||
1260 | Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1261 | return CreateUDiv(LHS, RHS, Name, true); | |||
1262 | } | |||
1263 | ||||
1264 | Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1265 | bool isExact = false) { | |||
1266 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1267 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1268 | return Insert(Folder.CreateSDiv(LC, RC, isExact), Name); | |||
1269 | if (!isExact) | |||
1270 | return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name); | |||
1271 | return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name); | |||
1272 | } | |||
1273 | ||||
1274 | Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1275 | return CreateSDiv(LHS, RHS, Name, true); | |||
1276 | } | |||
1277 | ||||
1278 | Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1279 | if (Value *V = foldConstant(Instruction::URem, LHS, RHS, Name)) return V; | |||
1280 | return Insert(BinaryOperator::CreateURem(LHS, RHS), Name); | |||
1281 | } | |||
1282 | ||||
1283 | Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1284 | if (Value *V = foldConstant(Instruction::SRem, LHS, RHS, Name)) return V; | |||
1285 | return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); | |||
1286 | } | |||
1287 | ||||
1288 | Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1289 | bool HasNUW = false, bool HasNSW = false) { | |||
1290 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1291 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1292 | return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name); | |||
1293 | return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name, | |||
1294 | HasNUW, HasNSW); | |||
1295 | } | |||
1296 | ||||
1297 | Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "", | |||
1298 | bool HasNUW = false, bool HasNSW = false) { | |||
1299 | return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name, | |||
1300 | HasNUW, HasNSW); | |||
1301 | } | |||
1302 | ||||
1303 | Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "", | |||
1304 | bool HasNUW = false, bool HasNSW = false) { | |||
1305 | return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name, | |||
1306 | HasNUW, HasNSW); | |||
1307 | } | |||
1308 | ||||
1309 | Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1310 | bool isExact = false) { | |||
1311 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1312 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1313 | return Insert(Folder.CreateLShr(LC, RC, isExact), Name); | |||
1314 | if (!isExact) | |||
1315 | return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); | |||
1316 | return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name); | |||
1317 | } | |||
1318 | ||||
1319 | Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "", | |||
1320 | bool isExact = false) { | |||
1321 | return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); | |||
1322 | } | |||
1323 | ||||
1324 | Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "", | |||
1325 | bool isExact = false) { | |||
1326 | return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); | |||
1327 | } | |||
1328 | ||||
1329 | Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "", | |||
1330 | bool isExact = false) { | |||
1331 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1332 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
1333 | return Insert(Folder.CreateAShr(LC, RC, isExact), Name); | |||
1334 | if (!isExact) | |||
1335 | return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); | |||
1336 | return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name); | |||
1337 | } | |||
1338 | ||||
1339 | Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "", | |||
1340 | bool isExact = false) { | |||
1341 | return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); | |||
1342 | } | |||
1343 | ||||
1344 | Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "", | |||
1345 | bool isExact = false) { | |||
1346 | return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); | |||
1347 | } | |||
1348 | ||||
1349 | Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1350 | if (auto *RC = dyn_cast<Constant>(RHS)) { | |||
1351 | if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isMinusOne()) | |||
1352 | return LHS; // LHS & -1 -> LHS | |||
1353 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1354 | return Insert(Folder.CreateAnd(LC, RC), Name); | |||
1355 | } | |||
1356 | return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); | |||
1357 | } | |||
1358 | ||||
1359 | Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") { | |||
1360 | return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name); | |||
1361 | } | |||
1362 | ||||
1363 | Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") { | |||
1364 | return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name); | |||
1365 | } | |||
1366 | ||||
1367 | Value *CreateAnd(ArrayRef<Value*> Ops) { | |||
1368 | assert(!Ops.empty())((!Ops.empty()) ? static_cast<void> (0) : __assert_fail ("!Ops.empty()", "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1368, __PRETTY_FUNCTION__)); | |||
1369 | Value *Accum = Ops[0]; | |||
1370 | for (unsigned i = 1; i < Ops.size(); i++) | |||
1371 | Accum = CreateAnd(Accum, Ops[i]); | |||
1372 | return Accum; | |||
1373 | } | |||
1374 | ||||
1375 | Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1376 | if (auto *RC = dyn_cast<Constant>(RHS)) { | |||
1377 | if (RC->isNullValue()) | |||
1378 | return LHS; // LHS | 0 -> LHS | |||
1379 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
1380 | return Insert(Folder.CreateOr(LC, RC), Name); | |||
1381 | } | |||
1382 | return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); | |||
1383 | } | |||
1384 | ||||
1385 | Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") { | |||
1386 | return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name); | |||
1387 | } | |||
1388 | ||||
1389 | Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") { | |||
1390 | return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name); | |||
1391 | } | |||
1392 | ||||
1393 | Value *CreateOr(ArrayRef<Value*> Ops) { | |||
1394 | assert(!Ops.empty())((!Ops.empty()) ? static_cast<void> (0) : __assert_fail ("!Ops.empty()", "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1394, __PRETTY_FUNCTION__)); | |||
1395 | Value *Accum = Ops[0]; | |||
1396 | for (unsigned i = 1; i < Ops.size(); i++) | |||
1397 | Accum = CreateOr(Accum, Ops[i]); | |||
1398 | return Accum; | |||
1399 | } | |||
1400 | ||||
1401 | Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
1402 | if (Value *V = foldConstant(Instruction::Xor, LHS, RHS, Name)) return V; | |||
1403 | return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); | |||
1404 | } | |||
1405 | ||||
1406 | Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") { | |||
1407 | return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name); | |||
1408 | } | |||
1409 | ||||
1410 | Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") { | |||
1411 | return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name); | |||
1412 | } | |||
1413 | ||||
1414 | Value *CreateFAdd(Value *L, Value *R, const Twine &Name = "", | |||
1415 | MDNode *FPMD = nullptr) { | |||
1416 | if (IsFPConstrained) | |||
1417 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd, | |||
1418 | L, R, nullptr, Name, FPMD); | |||
1419 | ||||
1420 | if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V; | |||
1421 | Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD, FMF); | |||
1422 | return Insert(I, Name); | |||
1423 | } | |||
1424 | ||||
1425 | /// Copy fast-math-flags from an instruction rather than using the builder's | |||
1426 | /// default FMF. | |||
1427 | Value *CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource, | |||
1428 | const Twine &Name = "") { | |||
1429 | if (IsFPConstrained) | |||
1430 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd, | |||
1431 | L, R, FMFSource, Name); | |||
1432 | ||||
1433 | if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V; | |||
1434 | Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), nullptr, | |||
1435 | FMFSource->getFastMathFlags()); | |||
1436 | return Insert(I, Name); | |||
1437 | } | |||
1438 | ||||
1439 | Value *CreateFSub(Value *L, Value *R, const Twine &Name = "", | |||
1440 | MDNode *FPMD = nullptr) { | |||
1441 | if (IsFPConstrained) | |||
1442 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub, | |||
1443 | L, R, nullptr, Name, FPMD); | |||
1444 | ||||
1445 | if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; | |||
1446 | Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD, FMF); | |||
1447 | return Insert(I, Name); | |||
1448 | } | |||
1449 | ||||
1450 | /// Copy fast-math-flags from an instruction rather than using the builder's | |||
1451 | /// default FMF. | |||
1452 | Value *CreateFSubFMF(Value *L, Value *R, Instruction *FMFSource, | |||
1453 | const Twine &Name = "") { | |||
1454 | if (IsFPConstrained) | |||
1455 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub, | |||
1456 | L, R, FMFSource, Name); | |||
1457 | ||||
1458 | if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; | |||
1459 | Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), nullptr, | |||
1460 | FMFSource->getFastMathFlags()); | |||
1461 | return Insert(I, Name); | |||
1462 | } | |||
1463 | ||||
1464 | Value *CreateFMul(Value *L, Value *R, const Twine &Name = "", | |||
1465 | MDNode *FPMD = nullptr) { | |||
1466 | if (IsFPConstrained) | |||
1467 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul, | |||
1468 | L, R, nullptr, Name, FPMD); | |||
1469 | ||||
1470 | if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; | |||
1471 | Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD, FMF); | |||
1472 | return Insert(I, Name); | |||
1473 | } | |||
1474 | ||||
1475 | /// Copy fast-math-flags from an instruction rather than using the builder's | |||
1476 | /// default FMF. | |||
1477 | Value *CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource, | |||
1478 | const Twine &Name = "") { | |||
1479 | if (IsFPConstrained) | |||
1480 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul, | |||
1481 | L, R, FMFSource, Name); | |||
1482 | ||||
1483 | if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; | |||
1484 | Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), nullptr, | |||
1485 | FMFSource->getFastMathFlags()); | |||
1486 | return Insert(I, Name); | |||
1487 | } | |||
1488 | ||||
1489 | Value *CreateFDiv(Value *L, Value *R, const Twine &Name = "", | |||
1490 | MDNode *FPMD = nullptr) { | |||
1491 | if (IsFPConstrained) | |||
1492 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv, | |||
1493 | L, R, nullptr, Name, FPMD); | |||
1494 | ||||
1495 | if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; | |||
1496 | Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD, FMF); | |||
1497 | return Insert(I, Name); | |||
1498 | } | |||
1499 | ||||
1500 | /// Copy fast-math-flags from an instruction rather than using the builder's | |||
1501 | /// default FMF. | |||
1502 | Value *CreateFDivFMF(Value *L, Value *R, Instruction *FMFSource, | |||
1503 | const Twine &Name = "") { | |||
1504 | if (IsFPConstrained) | |||
1505 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv, | |||
1506 | L, R, FMFSource, Name); | |||
1507 | ||||
1508 | if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; | |||
1509 | Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), nullptr, | |||
1510 | FMFSource->getFastMathFlags()); | |||
1511 | return Insert(I, Name); | |||
1512 | } | |||
1513 | ||||
1514 | Value *CreateFRem(Value *L, Value *R, const Twine &Name = "", | |||
1515 | MDNode *FPMD = nullptr) { | |||
1516 | if (IsFPConstrained) | |||
1517 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem, | |||
1518 | L, R, nullptr, Name, FPMD); | |||
1519 | ||||
1520 | if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; | |||
1521 | Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD, FMF); | |||
1522 | return Insert(I, Name); | |||
1523 | } | |||
1524 | ||||
1525 | /// Copy fast-math-flags from an instruction rather than using the builder's | |||
1526 | /// default FMF. | |||
1527 | Value *CreateFRemFMF(Value *L, Value *R, Instruction *FMFSource, | |||
1528 | const Twine &Name = "") { | |||
1529 | if (IsFPConstrained) | |||
1530 | return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem, | |||
1531 | L, R, FMFSource, Name); | |||
1532 | ||||
1533 | if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; | |||
1534 | Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), nullptr, | |||
1535 | FMFSource->getFastMathFlags()); | |||
1536 | return Insert(I, Name); | |||
1537 | } | |||
1538 | ||||
1539 | Value *CreateBinOp(Instruction::BinaryOps Opc, | |||
1540 | Value *LHS, Value *RHS, const Twine &Name = "", | |||
1541 | MDNode *FPMathTag = nullptr) { | |||
1542 | if (Value *V = foldConstant(Opc, LHS, RHS, Name)) return V; | |||
1543 | Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS); | |||
1544 | if (isa<FPMathOperator>(BinOp)) | |||
1545 | setFPAttrs(BinOp, FPMathTag, FMF); | |||
1546 | return Insert(BinOp, Name); | |||
1547 | } | |||
1548 | ||||
1549 | CallInst *CreateConstrainedFPBinOp( | |||
1550 | Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr, | |||
1551 | const Twine &Name = "", MDNode *FPMathTag = nullptr, | |||
1552 | Optional<fp::RoundingMode> Rounding = None, | |||
1553 | Optional<fp::ExceptionBehavior> Except = None) { | |||
1554 | Value *RoundingV = getConstrainedFPRounding(Rounding); | |||
1555 | Value *ExceptV = getConstrainedFPExcept(Except); | |||
1556 | ||||
1557 | FastMathFlags UseFMF = FMF; | |||
1558 | if (FMFSource) | |||
1559 | UseFMF = FMFSource->getFastMathFlags(); | |||
1560 | ||||
1561 | CallInst *C = CreateIntrinsic(ID, {L->getType()}, | |||
1562 | {L, R, RoundingV, ExceptV}, nullptr, Name); | |||
1563 | setConstrainedFPCallAttr(C); | |||
1564 | setFPAttrs(C, FPMathTag, UseFMF); | |||
1565 | return C; | |||
1566 | } | |||
1567 | ||||
1568 | Value *CreateNeg(Value *V, const Twine &Name = "", | |||
1569 | bool HasNUW = false, bool HasNSW = false) { | |||
1570 | if (auto *VC = dyn_cast<Constant>(V)) | |||
1571 | return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name); | |||
1572 | BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name); | |||
1573 | if (HasNUW) BO->setHasNoUnsignedWrap(); | |||
1574 | if (HasNSW) BO->setHasNoSignedWrap(); | |||
1575 | return BO; | |||
1576 | } | |||
1577 | ||||
1578 | Value *CreateNSWNeg(Value *V, const Twine &Name = "") { | |||
1579 | return CreateNeg(V, Name, false, true); | |||
1580 | } | |||
1581 | ||||
1582 | Value *CreateNUWNeg(Value *V, const Twine &Name = "") { | |||
1583 | return CreateNeg(V, Name, true, false); | |||
1584 | } | |||
1585 | ||||
1586 | Value *CreateFNeg(Value *V, const Twine &Name = "", | |||
1587 | MDNode *FPMathTag = nullptr) { | |||
1588 | if (auto *VC = dyn_cast<Constant>(V)) | |||
1589 | return Insert(Folder.CreateFNeg(VC), Name); | |||
1590 | return Insert(setFPAttrs(UnaryOperator::CreateFNeg(V), FPMathTag, FMF), | |||
1591 | Name); | |||
1592 | } | |||
1593 | ||||
1594 | /// Copy fast-math-flags from an instruction rather than using the builder's | |||
1595 | /// default FMF. | |||
1596 | Value *CreateFNegFMF(Value *V, Instruction *FMFSource, | |||
1597 | const Twine &Name = "") { | |||
1598 | if (auto *VC = dyn_cast<Constant>(V)) | |||
1599 | return Insert(Folder.CreateFNeg(VC), Name); | |||
1600 | return Insert(setFPAttrs(UnaryOperator::CreateFNeg(V), nullptr, | |||
1601 | FMFSource->getFastMathFlags()), | |||
1602 | Name); | |||
1603 | } | |||
1604 | ||||
1605 | Value *CreateNot(Value *V, const Twine &Name = "") { | |||
1606 | if (auto *VC = dyn_cast<Constant>(V)) | |||
1607 | return Insert(Folder.CreateNot(VC), Name); | |||
1608 | return Insert(BinaryOperator::CreateNot(V), Name); | |||
1609 | } | |||
1610 | ||||
1611 | Value *CreateUnOp(Instruction::UnaryOps Opc, | |||
1612 | Value *V, const Twine &Name = "", | |||
1613 | MDNode *FPMathTag = nullptr) { | |||
1614 | if (auto *VC = dyn_cast<Constant>(V)) | |||
1615 | return Insert(Folder.CreateUnOp(Opc, VC), Name); | |||
1616 | Instruction *UnOp = UnaryOperator::Create(Opc, V); | |||
1617 | if (isa<FPMathOperator>(UnOp)) | |||
1618 | setFPAttrs(UnOp, FPMathTag, FMF); | |||
1619 | return Insert(UnOp, Name); | |||
1620 | } | |||
1621 | ||||
1622 | /// Create either a UnaryOperator or BinaryOperator depending on \p Opc. | |||
1623 | /// Correct number of operands must be passed accordingly. | |||
1624 | Value *CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops, | |||
1625 | const Twine &Name = "", | |||
1626 | MDNode *FPMathTag = nullptr) { | |||
1627 | if (Instruction::isBinaryOp(Opc)) { | |||
1628 | assert(Ops.size() == 2 && "Invalid number of operands!")((Ops.size() == 2 && "Invalid number of operands!") ? static_cast<void> (0) : __assert_fail ("Ops.size() == 2 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1628, __PRETTY_FUNCTION__)); | |||
1629 | return CreateBinOp(static_cast<Instruction::BinaryOps>(Opc), | |||
1630 | Ops[0], Ops[1], Name, FPMathTag); | |||
1631 | } | |||
1632 | if (Instruction::isUnaryOp(Opc)) { | |||
1633 | assert(Ops.size() == 1 && "Invalid number of operands!")((Ops.size() == 1 && "Invalid number of operands!") ? static_cast<void> (0) : __assert_fail ("Ops.size() == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1633, __PRETTY_FUNCTION__)); | |||
1634 | return CreateUnOp(static_cast<Instruction::UnaryOps>(Opc), | |||
1635 | Ops[0], Name, FPMathTag); | |||
1636 | } | |||
1637 | llvm_unreachable("Unexpected opcode!")::llvm::llvm_unreachable_internal("Unexpected opcode!", "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 1637); | |||
1638 | } | |||
1639 | ||||
1640 | //===--------------------------------------------------------------------===// | |||
1641 | // Instruction creation methods: Memory Instructions | |||
1642 | //===--------------------------------------------------------------------===// | |||
1643 | ||||
1644 | AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace, | |||
1645 | Value *ArraySize = nullptr, const Twine &Name = "") { | |||
1646 | return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name); | |||
1647 | } | |||
1648 | ||||
1649 | AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr, | |||
1650 | const Twine &Name = "") { | |||
1651 | const DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); | |||
1652 | return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name); | |||
1653 | } | |||
1654 | ||||
1655 | /// Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of | |||
1656 | /// converting the string to 'bool' for the isVolatile parameter. | |||
1657 | LoadInst *CreateLoad(Type *Ty, Value *Ptr, const char *Name) { | |||
1658 | return Insert(new LoadInst(Ty, Ptr), Name); | |||
1659 | } | |||
1660 | ||||
1661 | LoadInst *CreateLoad(Type *Ty, Value *Ptr, const Twine &Name = "") { | |||
1662 | return Insert(new LoadInst(Ty, Ptr), Name); | |||
1663 | } | |||
1664 | ||||
1665 | LoadInst *CreateLoad(Type *Ty, Value *Ptr, bool isVolatile, | |||
1666 | const Twine &Name = "") { | |||
1667 | return Insert(new LoadInst(Ty, Ptr, Twine(), isVolatile), Name); | |||
1668 | } | |||
1669 | ||||
1670 | // Deprecated [opaque pointer types] | |||
1671 | LoadInst *CreateLoad(Value *Ptr, const char *Name) { | |||
1672 | return CreateLoad(Ptr->getType()->getPointerElementType(), Ptr, Name); | |||
1673 | } | |||
1674 | ||||
1675 | // Deprecated [opaque pointer types] | |||
1676 | LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") { | |||
1677 | return CreateLoad(Ptr->getType()->getPointerElementType(), Ptr, Name); | |||
1678 | } | |||
1679 | ||||
1680 | // Deprecated [opaque pointer types] | |||
1681 | LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") { | |||
1682 | return CreateLoad(Ptr->getType()->getPointerElementType(), Ptr, isVolatile, | |||
1683 | Name); | |||
1684 | } | |||
1685 | ||||
1686 | StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { | |||
1687 | return Insert(new StoreInst(Val, Ptr, isVolatile)); | |||
1688 | } | |||
1689 | ||||
1690 | /// Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' | |||
1691 | /// correctly, instead of converting the string to 'bool' for the isVolatile | |||
1692 | /// parameter. | |||
1693 | /// FIXME: Remove this function once transition to Align is over. | |||
1694 | /// Use the version that takes MaybeAlign instead of this one. | |||
1695 | LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align, | |||
1696 | const char *Name) { | |||
1697 | return CreateAlignedLoad(Ty, Ptr, MaybeAlign(Align), Name); | |||
1698 | } | |||
1699 | LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, | |||
1700 | const char *Name) { | |||
1701 | LoadInst *LI = CreateLoad(Ty, Ptr, Name); | |||
1702 | LI->setAlignment(Align); | |||
1703 | return LI; | |||
1704 | } | |||
1705 | /// FIXME: Remove this function once transition to Align is over. | |||
1706 | /// Use the version that takes MaybeAlign instead of this one. | |||
1707 | LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align, | |||
1708 | const Twine &Name = "") { | |||
1709 | return CreateAlignedLoad(Ty, Ptr, MaybeAlign(Align), Name); | |||
1710 | } | |||
1711 | LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, | |||
1712 | const Twine &Name = "") { | |||
1713 | LoadInst *LI = CreateLoad(Ty, Ptr, Name); | |||
1714 | LI->setAlignment(Align); | |||
1715 | return LI; | |||
1716 | } | |||
1717 | /// FIXME: Remove this function once transition to Align is over. | |||
1718 | /// Use the version that takes MaybeAlign instead of this one. | |||
1719 | LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align, | |||
1720 | bool isVolatile, const Twine &Name = "") { | |||
1721 | return CreateAlignedLoad(Ty, Ptr, MaybeAlign(Align), isVolatile, Name); | |||
1722 | } | |||
1723 | LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, | |||
1724 | bool isVolatile, const Twine &Name = "") { | |||
1725 | LoadInst *LI = CreateLoad(Ty, Ptr, isVolatile, Name); | |||
1726 | LI->setAlignment(Align); | |||
1727 | return LI; | |||
1728 | } | |||
1729 | ||||
1730 | // Deprecated [opaque pointer types] | |||
1731 | LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { | |||
1732 | return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, | |||
1733 | Align, Name); | |||
1734 | } | |||
1735 | // Deprecated [opaque pointer types] | |||
1736 | LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, | |||
1737 | const Twine &Name = "") { | |||
1738 | return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, | |||
1739 | Align, Name); | |||
1740 | } | |||
1741 | // Deprecated [opaque pointer types] | |||
1742 | LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile, | |||
1743 | const Twine &Name = "") { | |||
1744 | return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, | |||
1745 | Align, isVolatile, Name); | |||
1746 | } | |||
1747 | // Deprecated [opaque pointer types] | |||
1748 | LoadInst *CreateAlignedLoad(Value *Ptr, MaybeAlign Align, const char *Name) { | |||
1749 | return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, | |||
1750 | Align, Name); | |||
1751 | } | |||
1752 | // Deprecated [opaque pointer types] | |||
1753 | LoadInst *CreateAlignedLoad(Value *Ptr, MaybeAlign Align, | |||
1754 | const Twine &Name = "") { | |||
1755 | return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, | |||
1756 | Align, Name); | |||
1757 | } | |||
1758 | // Deprecated [opaque pointer types] | |||
1759 | LoadInst *CreateAlignedLoad(Value *Ptr, MaybeAlign Align, bool isVolatile, | |||
1760 | const Twine &Name = "") { | |||
1761 | return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, | |||
1762 | Align, isVolatile, Name); | |||
1763 | } | |||
1764 | ||||
1765 | StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align, | |||
1766 | bool isVolatile = false) { | |||
1767 | StoreInst *SI = CreateStore(Val, Ptr, isVolatile); | |||
1768 | SI->setAlignment(MaybeAlign(Align)); | |||
1769 | return SI; | |||
1770 | } | |||
1771 | StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, | |||
1772 | bool isVolatile = false) { | |||
1773 | return CreateAlignedStore(Val, Ptr, Align ? Align->value() : 0, isVolatile); | |||
1774 | } | |||
1775 | FenceInst *CreateFence(AtomicOrdering Ordering, | |||
1776 | SyncScope::ID SSID = SyncScope::System, | |||
1777 | const Twine &Name = "") { | |||
1778 | return Insert(new FenceInst(Context, Ordering, SSID), Name); | |||
1779 | } | |||
1780 | ||||
1781 | AtomicCmpXchgInst * | |||
1782 | CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New, | |||
1783 | AtomicOrdering SuccessOrdering, | |||
1784 | AtomicOrdering FailureOrdering, | |||
1785 | SyncScope::ID SSID = SyncScope::System) { | |||
1786 | return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, | |||
1787 | FailureOrdering, SSID)); | |||
1788 | } | |||
1789 | ||||
1790 | AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val, | |||
1791 | AtomicOrdering Ordering, | |||
1792 | SyncScope::ID SSID = SyncScope::System) { | |||
1793 | return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SSID)); | |||
1794 | } | |||
1795 | ||||
1796 | Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList, | |||
1797 | const Twine &Name = "") { | |||
1798 | return CreateGEP(nullptr, Ptr, IdxList, Name); | |||
1799 | } | |||
1800 | ||||
1801 | Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList, | |||
1802 | const Twine &Name = "") { | |||
1803 | if (auto *PC = dyn_cast<Constant>(Ptr)) { | |||
1804 | // Every index must be constant. | |||
1805 | size_t i, e; | |||
1806 | for (i = 0, e = IdxList.size(); i != e; ++i) | |||
1807 | if (!isa<Constant>(IdxList[i])) | |||
1808 | break; | |||
1809 | if (i == e) | |||
1810 | return Insert(Folder.CreateGetElementPtr(Ty, PC, IdxList), Name); | |||
1811 | } | |||
1812 | return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name); | |||
1813 | } | |||
1814 | ||||
1815 | Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList, | |||
1816 | const Twine &Name = "") { | |||
1817 | return CreateInBoundsGEP(nullptr, Ptr, IdxList, Name); | |||
1818 | } | |||
1819 | ||||
1820 | Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList, | |||
1821 | const Twine &Name = "") { | |||
1822 | if (auto *PC = dyn_cast<Constant>(Ptr)) { | |||
1823 | // Every index must be constant. | |||
1824 | size_t i, e; | |||
1825 | for (i = 0, e = IdxList.size(); i != e; ++i) | |||
1826 | if (!isa<Constant>(IdxList[i])) | |||
1827 | break; | |||
1828 | if (i == e) | |||
1829 | return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IdxList), | |||
1830 | Name); | |||
1831 | } | |||
1832 | return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList), Name); | |||
1833 | } | |||
1834 | ||||
1835 | Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { | |||
1836 | return CreateGEP(nullptr, Ptr, Idx, Name); | |||
1837 | } | |||
1838 | ||||
1839 | Value *CreateGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") { | |||
1840 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1841 | if (auto *IC = dyn_cast<Constant>(Idx)) | |||
1842 | return Insert(Folder.CreateGetElementPtr(Ty, PC, IC), Name); | |||
1843 | return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); | |||
1844 | } | |||
1845 | ||||
1846 | Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx, | |||
1847 | const Twine &Name = "") { | |||
1848 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1849 | if (auto *IC = dyn_cast<Constant>(Idx)) | |||
1850 | return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IC), Name); | |||
1851 | return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); | |||
1852 | } | |||
1853 | ||||
1854 | Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { | |||
1855 | return CreateConstGEP1_32(nullptr, Ptr, Idx0, Name); | |||
1856 | } | |||
1857 | ||||
1858 | Value *CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, | |||
1859 | const Twine &Name = "") { | |||
1860 | Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); | |||
1861 | ||||
1862 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1863 | return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name); | |||
1864 | ||||
1865 | return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); | |||
1866 | } | |||
1867 | ||||
1868 | Value *CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, | |||
1869 | const Twine &Name = "") { | |||
1870 | Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); | |||
1871 | ||||
1872 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1873 | return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name); | |||
1874 | ||||
1875 | return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); | |||
1876 | } | |||
1877 | ||||
1878 | Value *CreateConstGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, | |||
1879 | const Twine &Name = "") { | |||
1880 | Value *Idxs[] = { | |||
1881 | ConstantInt::get(Type::getInt32Ty(Context), Idx0), | |||
1882 | ConstantInt::get(Type::getInt32Ty(Context), Idx1) | |||
1883 | }; | |||
1884 | ||||
1885 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1886 | return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name); | |||
1887 | ||||
1888 | return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name); | |||
1889 | } | |||
1890 | ||||
1891 | Value *CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, | |||
1892 | unsigned Idx1, const Twine &Name = "") { | |||
1893 | Value *Idxs[] = { | |||
1894 | ConstantInt::get(Type::getInt32Ty(Context), Idx0), | |||
1895 | ConstantInt::get(Type::getInt32Ty(Context), Idx1) | |||
1896 | }; | |||
1897 | ||||
1898 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1899 | return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name); | |||
1900 | ||||
1901 | return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name); | |||
1902 | } | |||
1903 | ||||
1904 | Value *CreateConstGEP1_64(Type *Ty, Value *Ptr, uint64_t Idx0, | |||
1905 | const Twine &Name = "") { | |||
1906 | Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); | |||
1907 | ||||
1908 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1909 | return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name); | |||
1910 | ||||
1911 | return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); | |||
1912 | } | |||
1913 | ||||
1914 | Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { | |||
1915 | return CreateConstGEP1_64(nullptr, Ptr, Idx0, Name); | |||
1916 | } | |||
1917 | ||||
1918 | Value *CreateConstInBoundsGEP1_64(Type *Ty, Value *Ptr, uint64_t Idx0, | |||
1919 | const Twine &Name = "") { | |||
1920 | Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); | |||
1921 | ||||
1922 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1923 | return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name); | |||
1924 | ||||
1925 | return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); | |||
1926 | } | |||
1927 | ||||
1928 | Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0, | |||
1929 | const Twine &Name = "") { | |||
1930 | return CreateConstInBoundsGEP1_64(nullptr, Ptr, Idx0, Name); | |||
1931 | } | |||
1932 | ||||
1933 | Value *CreateConstGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, uint64_t Idx1, | |||
1934 | const Twine &Name = "") { | |||
1935 | Value *Idxs[] = { | |||
1936 | ConstantInt::get(Type::getInt64Ty(Context), Idx0), | |||
1937 | ConstantInt::get(Type::getInt64Ty(Context), Idx1) | |||
1938 | }; | |||
1939 | ||||
1940 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1941 | return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name); | |||
1942 | ||||
1943 | return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name); | |||
1944 | } | |||
1945 | ||||
1946 | Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, | |||
1947 | const Twine &Name = "") { | |||
1948 | return CreateConstGEP2_64(nullptr, Ptr, Idx0, Idx1, Name); | |||
1949 | } | |||
1950 | ||||
1951 | Value *CreateConstInBoundsGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, | |||
1952 | uint64_t Idx1, const Twine &Name = "") { | |||
1953 | Value *Idxs[] = { | |||
1954 | ConstantInt::get(Type::getInt64Ty(Context), Idx0), | |||
1955 | ConstantInt::get(Type::getInt64Ty(Context), Idx1) | |||
1956 | }; | |||
1957 | ||||
1958 | if (auto *PC = dyn_cast<Constant>(Ptr)) | |||
1959 | return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name); | |||
1960 | ||||
1961 | return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name); | |||
1962 | } | |||
1963 | ||||
1964 | Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, | |||
1965 | const Twine &Name = "") { | |||
1966 | return CreateConstInBoundsGEP2_64(nullptr, Ptr, Idx0, Idx1, Name); | |||
1967 | } | |||
1968 | ||||
1969 | Value *CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, | |||
1970 | const Twine &Name = "") { | |||
1971 | return CreateConstInBoundsGEP2_32(Ty, Ptr, 0, Idx, Name); | |||
1972 | } | |||
1973 | ||||
1974 | Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { | |||
1975 | return CreateConstInBoundsGEP2_32(nullptr, Ptr, 0, Idx, Name); | |||
1976 | } | |||
1977 | ||||
1978 | /// Same as CreateGlobalString, but return a pointer with "i8*" type | |||
1979 | /// instead of a pointer to array of i8. | |||
1980 | Constant *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "", | |||
1981 | unsigned AddressSpace = 0) { | |||
1982 | GlobalVariable *GV = CreateGlobalString(Str, Name, AddressSpace); | |||
1983 | Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); | |||
1984 | Constant *Indices[] = {Zero, Zero}; | |||
1985 | return ConstantExpr::getInBoundsGetElementPtr(GV->getValueType(), GV, | |||
1986 | Indices); | |||
1987 | } | |||
1988 | ||||
1989 | //===--------------------------------------------------------------------===// | |||
1990 | // Instruction creation methods: Cast/Conversion Operators | |||
1991 | //===--------------------------------------------------------------------===// | |||
1992 | ||||
1993 | Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") { | |||
1994 | return CreateCast(Instruction::Trunc, V, DestTy, Name); | |||
1995 | } | |||
1996 | ||||
1997 | Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") { | |||
1998 | return CreateCast(Instruction::ZExt, V, DestTy, Name); | |||
1999 | } | |||
2000 | ||||
2001 | Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { | |||
2002 | return CreateCast(Instruction::SExt, V, DestTy, Name); | |||
2003 | } | |||
2004 | ||||
2005 | /// Create a ZExt or Trunc from the integer value V to DestTy. Return | |||
2006 | /// the value untouched if the type of V is already DestTy. | |||
2007 | Value *CreateZExtOrTrunc(Value *V, Type *DestTy, | |||
2008 | const Twine &Name = "") { | |||
2009 | assert(V->getType()->isIntOrIntVectorTy() &&((V->getType()->isIntOrIntVectorTy() && DestTy-> isIntOrIntVectorTy() && "Can only zero extend/truncate integers!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && \"Can only zero extend/truncate integers!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2011, __PRETTY_FUNCTION__)) | |||
2010 | DestTy->isIntOrIntVectorTy() &&((V->getType()->isIntOrIntVectorTy() && DestTy-> isIntOrIntVectorTy() && "Can only zero extend/truncate integers!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && \"Can only zero extend/truncate integers!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2011, __PRETTY_FUNCTION__)) | |||
2011 | "Can only zero extend/truncate integers!")((V->getType()->isIntOrIntVectorTy() && DestTy-> isIntOrIntVectorTy() && "Can only zero extend/truncate integers!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && \"Can only zero extend/truncate integers!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2011, __PRETTY_FUNCTION__)); | |||
2012 | Type *VTy = V->getType(); | |||
2013 | if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) | |||
2014 | return CreateZExt(V, DestTy, Name); | |||
2015 | if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) | |||
2016 | return CreateTrunc(V, DestTy, Name); | |||
2017 | return V; | |||
2018 | } | |||
2019 | ||||
2020 | /// Create a SExt or Trunc from the integer value V to DestTy. Return | |||
2021 | /// the value untouched if the type of V is already DestTy. | |||
2022 | Value *CreateSExtOrTrunc(Value *V, Type *DestTy, | |||
2023 | const Twine &Name = "") { | |||
2024 | assert(V->getType()->isIntOrIntVectorTy() &&((V->getType()->isIntOrIntVectorTy() && DestTy-> isIntOrIntVectorTy() && "Can only sign extend/truncate integers!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && \"Can only sign extend/truncate integers!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2026, __PRETTY_FUNCTION__)) | |||
2025 | DestTy->isIntOrIntVectorTy() &&((V->getType()->isIntOrIntVectorTy() && DestTy-> isIntOrIntVectorTy() && "Can only sign extend/truncate integers!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && \"Can only sign extend/truncate integers!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2026, __PRETTY_FUNCTION__)) | |||
2026 | "Can only sign extend/truncate integers!")((V->getType()->isIntOrIntVectorTy() && DestTy-> isIntOrIntVectorTy() && "Can only sign extend/truncate integers!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && \"Can only sign extend/truncate integers!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2026, __PRETTY_FUNCTION__)); | |||
2027 | Type *VTy = V->getType(); | |||
2028 | if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) | |||
2029 | return CreateSExt(V, DestTy, Name); | |||
2030 | if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) | |||
2031 | return CreateTrunc(V, DestTy, Name); | |||
2032 | return V; | |||
2033 | } | |||
2034 | ||||
2035 | Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = "") { | |||
2036 | if (IsFPConstrained) | |||
2037 | return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fptoui, | |||
2038 | V, DestTy, nullptr, Name); | |||
2039 | return CreateCast(Instruction::FPToUI, V, DestTy, Name); | |||
2040 | } | |||
2041 | ||||
2042 | Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = "") { | |||
2043 | if (IsFPConstrained) | |||
2044 | return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fptosi, | |||
2045 | V, DestTy, nullptr, Name); | |||
2046 | return CreateCast(Instruction::FPToSI, V, DestTy, Name); | |||
2047 | } | |||
2048 | ||||
2049 | Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ | |||
2050 | if (IsFPConstrained) | |||
2051 | return CreateConstrainedFPCast(Intrinsic::experimental_constrained_uitofp, | |||
2052 | V, DestTy, nullptr, Name); | |||
2053 | return CreateCast(Instruction::UIToFP, V, DestTy, Name); | |||
2054 | } | |||
2055 | ||||
2056 | Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ | |||
2057 | if (IsFPConstrained) | |||
2058 | return CreateConstrainedFPCast(Intrinsic::experimental_constrained_sitofp, | |||
2059 | V, DestTy, nullptr, Name); | |||
2060 | return CreateCast(Instruction::SIToFP, V, DestTy, Name); | |||
2061 | } | |||
2062 | ||||
2063 | Value *CreateFPTrunc(Value *V, Type *DestTy, | |||
2064 | const Twine &Name = "") { | |||
2065 | if (IsFPConstrained) | |||
2066 | return CreateConstrainedFPCast( | |||
2067 | Intrinsic::experimental_constrained_fptrunc, V, DestTy, nullptr, | |||
2068 | Name); | |||
2069 | return CreateCast(Instruction::FPTrunc, V, DestTy, Name); | |||
2070 | } | |||
2071 | ||||
2072 | Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") { | |||
2073 | if (IsFPConstrained) | |||
2074 | return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fpext, | |||
2075 | V, DestTy, nullptr, Name); | |||
2076 | return CreateCast(Instruction::FPExt, V, DestTy, Name); | |||
2077 | } | |||
2078 | ||||
2079 | Value *CreatePtrToInt(Value *V, Type *DestTy, | |||
2080 | const Twine &Name = "") { | |||
2081 | return CreateCast(Instruction::PtrToInt, V, DestTy, Name); | |||
2082 | } | |||
2083 | ||||
2084 | Value *CreateIntToPtr(Value *V, Type *DestTy, | |||
2085 | const Twine &Name = "") { | |||
2086 | return CreateCast(Instruction::IntToPtr, V, DestTy, Name); | |||
2087 | } | |||
2088 | ||||
2089 | Value *CreateBitCast(Value *V, Type *DestTy, | |||
2090 | const Twine &Name = "") { | |||
2091 | return CreateCast(Instruction::BitCast, V, DestTy, Name); | |||
2092 | } | |||
2093 | ||||
2094 | Value *CreateAddrSpaceCast(Value *V, Type *DestTy, | |||
2095 | const Twine &Name = "") { | |||
2096 | return CreateCast(Instruction::AddrSpaceCast, V, DestTy, Name); | |||
2097 | } | |||
2098 | ||||
2099 | Value *CreateZExtOrBitCast(Value *V, Type *DestTy, | |||
2100 | const Twine &Name = "") { | |||
2101 | if (V->getType() == DestTy) | |||
2102 | return V; | |||
2103 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2104 | return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name); | |||
2105 | return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name); | |||
2106 | } | |||
2107 | ||||
2108 | Value *CreateSExtOrBitCast(Value *V, Type *DestTy, | |||
2109 | const Twine &Name = "") { | |||
2110 | if (V->getType() == DestTy) | |||
2111 | return V; | |||
2112 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2113 | return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name); | |||
2114 | return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name); | |||
2115 | } | |||
2116 | ||||
2117 | Value *CreateTruncOrBitCast(Value *V, Type *DestTy, | |||
2118 | const Twine &Name = "") { | |||
2119 | if (V->getType() == DestTy) | |||
2120 | return V; | |||
2121 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2122 | return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name); | |||
2123 | return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name); | |||
2124 | } | |||
2125 | ||||
2126 | Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, | |||
2127 | const Twine &Name = "") { | |||
2128 | if (V->getType() == DestTy) | |||
| ||||
2129 | return V; | |||
2130 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2131 | return Insert(Folder.CreateCast(Op, VC, DestTy), Name); | |||
2132 | return Insert(CastInst::Create(Op, V, DestTy), Name); | |||
2133 | } | |||
2134 | ||||
2135 | Value *CreatePointerCast(Value *V, Type *DestTy, | |||
2136 | const Twine &Name = "") { | |||
2137 | if (V->getType() == DestTy) | |||
2138 | return V; | |||
2139 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2140 | return Insert(Folder.CreatePointerCast(VC, DestTy), Name); | |||
2141 | return Insert(CastInst::CreatePointerCast(V, DestTy), Name); | |||
2142 | } | |||
2143 | ||||
2144 | Value *CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy, | |||
2145 | const Twine &Name = "") { | |||
2146 | if (V->getType() == DestTy) | |||
2147 | return V; | |||
2148 | ||||
2149 | if (auto *VC = dyn_cast<Constant>(V)) { | |||
2150 | return Insert(Folder.CreatePointerBitCastOrAddrSpaceCast(VC, DestTy), | |||
2151 | Name); | |||
2152 | } | |||
2153 | ||||
2154 | return Insert(CastInst::CreatePointerBitCastOrAddrSpaceCast(V, DestTy), | |||
2155 | Name); | |||
2156 | } | |||
2157 | ||||
2158 | Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, | |||
2159 | const Twine &Name = "") { | |||
2160 | if (V->getType() == DestTy) | |||
2161 | return V; | |||
2162 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2163 | return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name); | |||
2164 | return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); | |||
2165 | } | |||
2166 | ||||
2167 | Value *CreateBitOrPointerCast(Value *V, Type *DestTy, | |||
2168 | const Twine &Name = "") { | |||
2169 | if (V->getType() == DestTy) | |||
2170 | return V; | |||
2171 | if (V->getType()->isPtrOrPtrVectorTy() && DestTy->isIntOrIntVectorTy()) | |||
2172 | return CreatePtrToInt(V, DestTy, Name); | |||
2173 | if (V->getType()->isIntOrIntVectorTy() && DestTy->isPtrOrPtrVectorTy()) | |||
2174 | return CreateIntToPtr(V, DestTy, Name); | |||
2175 | ||||
2176 | return CreateBitCast(V, DestTy, Name); | |||
2177 | } | |||
2178 | ||||
2179 | Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { | |||
2180 | if (V->getType() == DestTy) | |||
2181 | return V; | |||
2182 | if (auto *VC = dyn_cast<Constant>(V)) | |||
2183 | return Insert(Folder.CreateFPCast(VC, DestTy), Name); | |||
2184 | return Insert(CastInst::CreateFPCast(V, DestTy), Name); | |||
2185 | } | |||
2186 | ||||
2187 | CallInst *CreateConstrainedFPCast( | |||
2188 | Intrinsic::ID ID, Value *V, Type *DestTy, | |||
2189 | Instruction *FMFSource = nullptr, const Twine &Name = "", | |||
2190 | MDNode *FPMathTag = nullptr, | |||
2191 | Optional<fp::RoundingMode> Rounding = None, | |||
2192 | Optional<fp::ExceptionBehavior> Except = None) { | |||
2193 | Value *ExceptV = getConstrainedFPExcept(Except); | |||
2194 | ||||
2195 | FastMathFlags UseFMF = FMF; | |||
2196 | if (FMFSource) | |||
2197 | UseFMF = FMFSource->getFastMathFlags(); | |||
2198 | ||||
2199 | CallInst *C; | |||
2200 | bool HasRoundingMD = false; | |||
2201 | switch (ID) { | |||
2202 | default: | |||
2203 | break; | |||
2204 | #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \ | |||
2205 | case Intrinsic::INTRINSIC: \ | |||
2206 | HasRoundingMD = ROUND_MODE; \ | |||
2207 | break; | |||
2208 | #include "llvm/IR/ConstrainedOps.def" | |||
2209 | } | |||
2210 | if (HasRoundingMD) { | |||
2211 | Value *RoundingV = getConstrainedFPRounding(Rounding); | |||
2212 | C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV}, | |||
2213 | nullptr, Name); | |||
2214 | } else | |||
2215 | C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr, | |||
2216 | Name); | |||
2217 | ||||
2218 | setConstrainedFPCallAttr(C); | |||
2219 | ||||
2220 | if (isa<FPMathOperator>(C)) | |||
2221 | setFPAttrs(C, FPMathTag, UseFMF); | |||
2222 | return C; | |||
2223 | } | |||
2224 | ||||
2225 | // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a | |||
2226 | // compile time error, instead of converting the string to bool for the | |||
2227 | // isSigned parameter. | |||
2228 | Value *CreateIntCast(Value *, Type *, const char *) = delete; | |||
2229 | ||||
2230 | //===--------------------------------------------------------------------===// | |||
2231 | // Instruction creation methods: Compare Instructions | |||
2232 | //===--------------------------------------------------------------------===// | |||
2233 | ||||
2234 | Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2235 | return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name); | |||
2236 | } | |||
2237 | ||||
2238 | Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2239 | return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name); | |||
2240 | } | |||
2241 | ||||
2242 | Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2243 | return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name); | |||
2244 | } | |||
2245 | ||||
2246 | Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2247 | return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name); | |||
2248 | } | |||
2249 | ||||
2250 | Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2251 | return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name); | |||
2252 | } | |||
2253 | ||||
2254 | Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2255 | return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name); | |||
2256 | } | |||
2257 | ||||
2258 | Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2259 | return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name); | |||
2260 | } | |||
2261 | ||||
2262 | Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2263 | return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name); | |||
2264 | } | |||
2265 | ||||
2266 | Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2267 | return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name); | |||
2268 | } | |||
2269 | ||||
2270 | Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2271 | return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name); | |||
2272 | } | |||
2273 | ||||
2274 | Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2275 | MDNode *FPMathTag = nullptr) { | |||
2276 | return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name, FPMathTag); | |||
2277 | } | |||
2278 | ||||
2279 | Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2280 | MDNode *FPMathTag = nullptr) { | |||
2281 | return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name, FPMathTag); | |||
2282 | } | |||
2283 | ||||
2284 | Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2285 | MDNode *FPMathTag = nullptr) { | |||
2286 | return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name, FPMathTag); | |||
2287 | } | |||
2288 | ||||
2289 | Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2290 | MDNode *FPMathTag = nullptr) { | |||
2291 | return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name, FPMathTag); | |||
2292 | } | |||
2293 | ||||
2294 | Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2295 | MDNode *FPMathTag = nullptr) { | |||
2296 | return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name, FPMathTag); | |||
2297 | } | |||
2298 | ||||
2299 | Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2300 | MDNode *FPMathTag = nullptr) { | |||
2301 | return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name, FPMathTag); | |||
2302 | } | |||
2303 | ||||
2304 | Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2305 | MDNode *FPMathTag = nullptr) { | |||
2306 | return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name, FPMathTag); | |||
2307 | } | |||
2308 | ||||
2309 | Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2310 | MDNode *FPMathTag = nullptr) { | |||
2311 | return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name, FPMathTag); | |||
2312 | } | |||
2313 | ||||
2314 | Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2315 | MDNode *FPMathTag = nullptr) { | |||
2316 | return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name, FPMathTag); | |||
2317 | } | |||
2318 | ||||
2319 | Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2320 | MDNode *FPMathTag = nullptr) { | |||
2321 | return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name, FPMathTag); | |||
2322 | } | |||
2323 | ||||
2324 | Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2325 | MDNode *FPMathTag = nullptr) { | |||
2326 | return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name, FPMathTag); | |||
2327 | } | |||
2328 | ||||
2329 | Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2330 | MDNode *FPMathTag = nullptr) { | |||
2331 | return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name, FPMathTag); | |||
2332 | } | |||
2333 | ||||
2334 | Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2335 | MDNode *FPMathTag = nullptr) { | |||
2336 | return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name, FPMathTag); | |||
2337 | } | |||
2338 | ||||
2339 | Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "", | |||
2340 | MDNode *FPMathTag = nullptr) { | |||
2341 | return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name, FPMathTag); | |||
2342 | } | |||
2343 | ||||
2344 | Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, | |||
2345 | const Twine &Name = "") { | |||
2346 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
2347 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
2348 | return Insert(Folder.CreateICmp(P, LC, RC), Name); | |||
2349 | return Insert(new ICmpInst(P, LHS, RHS), Name); | |||
2350 | } | |||
2351 | ||||
2352 | Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, | |||
2353 | const Twine &Name = "", MDNode *FPMathTag = nullptr) { | |||
2354 | if (auto *LC = dyn_cast<Constant>(LHS)) | |||
2355 | if (auto *RC = dyn_cast<Constant>(RHS)) | |||
2356 | return Insert(Folder.CreateFCmp(P, LC, RC), Name); | |||
2357 | return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name); | |||
2358 | } | |||
2359 | ||||
2360 | //===--------------------------------------------------------------------===// | |||
2361 | // Instruction creation methods: Other Instructions | |||
2362 | //===--------------------------------------------------------------------===// | |||
2363 | ||||
2364 | PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues, | |||
2365 | const Twine &Name = "") { | |||
2366 | PHINode *Phi = PHINode::Create(Ty, NumReservedValues); | |||
2367 | if (isa<FPMathOperator>(Phi)) | |||
2368 | setFPAttrs(Phi, nullptr /* MDNode* */, FMF); | |||
2369 | return Insert(Phi, Name); | |||
2370 | } | |||
2371 | ||||
2372 | CallInst *CreateCall(FunctionType *FTy, Value *Callee, | |||
2373 | ArrayRef<Value *> Args = None, const Twine &Name = "", | |||
2374 | MDNode *FPMathTag = nullptr) { | |||
2375 | CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles); | |||
2376 | if (IsFPConstrained) | |||
2377 | setConstrainedFPCallAttr(CI); | |||
2378 | if (isa<FPMathOperator>(CI)) | |||
2379 | setFPAttrs(CI, FPMathTag, FMF); | |||
2380 | return Insert(CI, Name); | |||
2381 | } | |||
2382 | ||||
2383 | CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef<Value *> Args, | |||
2384 | ArrayRef<OperandBundleDef> OpBundles, | |||
2385 | const Twine &Name = "", MDNode *FPMathTag = nullptr) { | |||
2386 | CallInst *CI = CallInst::Create(FTy, Callee, Args, OpBundles); | |||
2387 | if (IsFPConstrained) | |||
2388 | setConstrainedFPCallAttr(CI); | |||
2389 | if (isa<FPMathOperator>(CI)) | |||
2390 | setFPAttrs(CI, FPMathTag, FMF); | |||
2391 | return Insert(CI, Name); | |||
2392 | } | |||
2393 | ||||
2394 | CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = None, | |||
2395 | const Twine &Name = "", MDNode *FPMathTag = nullptr) { | |||
2396 | return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, Name, | |||
2397 | FPMathTag); | |||
2398 | } | |||
2399 | ||||
2400 | CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args, | |||
2401 | ArrayRef<OperandBundleDef> OpBundles, | |||
2402 | const Twine &Name = "", MDNode *FPMathTag = nullptr) { | |||
2403 | return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, | |||
2404 | OpBundles, Name, FPMathTag); | |||
2405 | } | |||
2406 | ||||
2407 | // Deprecated [opaque pointer types] | |||
2408 | CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None, | |||
2409 | const Twine &Name = "", MDNode *FPMathTag = nullptr) { | |||
2410 | return CreateCall( | |||
2411 | cast<FunctionType>(Callee->getType()->getPointerElementType()), Callee, | |||
2412 | Args, Name, FPMathTag); | |||
2413 | } | |||
2414 | ||||
2415 | // Deprecated [opaque pointer types] | |||
2416 | CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args, | |||
2417 | ArrayRef<OperandBundleDef> OpBundles, | |||
2418 | const Twine &Name = "", MDNode *FPMathTag = nullptr) { | |||
2419 | return CreateCall( | |||
2420 | cast<FunctionType>(Callee->getType()->getPointerElementType()), Callee, | |||
2421 | Args, OpBundles, Name, FPMathTag); | |||
2422 | } | |||
2423 | ||||
2424 | CallInst *CreateConstrainedFPCall( | |||
2425 | Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "", | |||
2426 | Optional<fp::RoundingMode> Rounding = None, | |||
2427 | Optional<fp::ExceptionBehavior> Except = None) { | |||
2428 | llvm::SmallVector<Value *, 6> UseArgs; | |||
2429 | ||||
2430 | for (auto *OneArg : Args) | |||
2431 | UseArgs.push_back(OneArg); | |||
2432 | bool HasRoundingMD = false; | |||
2433 | switch (Callee->getIntrinsicID()) { | |||
2434 | default: | |||
2435 | break; | |||
2436 | #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \ | |||
2437 | case Intrinsic::INTRINSIC: \ | |||
2438 | HasRoundingMD = ROUND_MODE; \ | |||
2439 | break; | |||
2440 | #include "llvm/IR/ConstrainedOps.def" | |||
2441 | } | |||
2442 | if (HasRoundingMD) | |||
2443 | UseArgs.push_back(getConstrainedFPRounding(Rounding)); | |||
2444 | UseArgs.push_back(getConstrainedFPExcept(Except)); | |||
2445 | ||||
2446 | CallInst *C = CreateCall(Callee, UseArgs, Name); | |||
2447 | setConstrainedFPCallAttr(C); | |||
2448 | return C; | |||
2449 | } | |||
2450 | ||||
2451 | Value *CreateSelect(Value *C, Value *True, Value *False, | |||
2452 | const Twine &Name = "", Instruction *MDFrom = nullptr) { | |||
2453 | if (auto *CC = dyn_cast<Constant>(C)) | |||
2454 | if (auto *TC = dyn_cast<Constant>(True)) | |||
2455 | if (auto *FC = dyn_cast<Constant>(False)) | |||
2456 | return Insert(Folder.CreateSelect(CC, TC, FC), Name); | |||
2457 | ||||
2458 | SelectInst *Sel = SelectInst::Create(C, True, False); | |||
2459 | if (MDFrom) { | |||
2460 | MDNode *Prof = MDFrom->getMetadata(LLVMContext::MD_prof); | |||
2461 | MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable); | |||
2462 | Sel = addBranchMetadata(Sel, Prof, Unpred); | |||
2463 | } | |||
2464 | if (isa<FPMathOperator>(Sel)) | |||
2465 | setFPAttrs(Sel, nullptr /* MDNode* */, FMF); | |||
2466 | return Insert(Sel, Name); | |||
2467 | } | |||
2468 | ||||
2469 | VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") { | |||
2470 | return Insert(new VAArgInst(List, Ty), Name); | |||
2471 | } | |||
2472 | ||||
2473 | Value *CreateExtractElement(Value *Vec, Value *Idx, | |||
2474 | const Twine &Name = "") { | |||
2475 | if (auto *VC = dyn_cast<Constant>(Vec)) | |||
2476 | if (auto *IC = dyn_cast<Constant>(Idx)) | |||
2477 | return Insert(Folder.CreateExtractElement(VC, IC), Name); | |||
2478 | return Insert(ExtractElementInst::Create(Vec, Idx), Name); | |||
2479 | } | |||
2480 | ||||
2481 | Value *CreateExtractElement(Value *Vec, uint64_t Idx, | |||
2482 | const Twine &Name = "") { | |||
2483 | return CreateExtractElement(Vec, getInt64(Idx), Name); | |||
2484 | } | |||
2485 | ||||
2486 | Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, | |||
2487 | const Twine &Name = "") { | |||
2488 | if (auto *VC = dyn_cast<Constant>(Vec)) | |||
2489 | if (auto *NC = dyn_cast<Constant>(NewElt)) | |||
2490 | if (auto *IC = dyn_cast<Constant>(Idx)) | |||
2491 | return Insert(Folder.CreateInsertElement(VC, NC, IC), Name); | |||
2492 | return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name); | |||
2493 | } | |||
2494 | ||||
2495 | Value *CreateInsertElement(Value *Vec, Value *NewElt, uint64_t Idx, | |||
2496 | const Twine &Name = "") { | |||
2497 | return CreateInsertElement(Vec, NewElt, getInt64(Idx), Name); | |||
2498 | } | |||
2499 | ||||
2500 | Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask, | |||
2501 | const Twine &Name = "") { | |||
2502 | if (auto *V1C = dyn_cast<Constant>(V1)) | |||
2503 | if (auto *V2C = dyn_cast<Constant>(V2)) | |||
2504 | if (auto *MC = dyn_cast<Constant>(Mask)) | |||
2505 | return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name); | |||
2506 | return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); | |||
2507 | } | |||
2508 | ||||
2509 | Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef<uint32_t> IntMask, | |||
2510 | const Twine &Name = "") { | |||
2511 | Value *Mask = ConstantDataVector::get(Context, IntMask); | |||
2512 | return CreateShuffleVector(V1, V2, Mask, Name); | |||
2513 | } | |||
2514 | ||||
2515 | Value *CreateExtractValue(Value *Agg, | |||
2516 | ArrayRef<unsigned> Idxs, | |||
2517 | const Twine &Name = "") { | |||
2518 | if (auto *AggC = dyn_cast<Constant>(Agg)) | |||
2519 | return Insert(Folder.CreateExtractValue(AggC, Idxs), Name); | |||
2520 | return Insert(ExtractValueInst::Create(Agg, Idxs), Name); | |||
2521 | } | |||
2522 | ||||
2523 | Value *CreateInsertValue(Value *Agg, Value *Val, | |||
2524 | ArrayRef<unsigned> Idxs, | |||
2525 | const Twine &Name = "") { | |||
2526 | if (auto *AggC = dyn_cast<Constant>(Agg)) | |||
2527 | if (auto *ValC = dyn_cast<Constant>(Val)) | |||
2528 | return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name); | |||
2529 | return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); | |||
2530 | } | |||
2531 | ||||
2532 | LandingPadInst *CreateLandingPad(Type *Ty, unsigned NumClauses, | |||
2533 | const Twine &Name = "") { | |||
2534 | return Insert(LandingPadInst::Create(Ty, NumClauses), Name); | |||
2535 | } | |||
2536 | ||||
2537 | Value *CreateFreeze(Value *V, const Twine &Name = "") { | |||
2538 | return Insert(new FreezeInst(V), Name); | |||
2539 | } | |||
2540 | ||||
2541 | //===--------------------------------------------------------------------===// | |||
2542 | // Utility creation methods | |||
2543 | //===--------------------------------------------------------------------===// | |||
2544 | ||||
2545 | /// Return an i1 value testing if \p Arg is null. | |||
2546 | Value *CreateIsNull(Value *Arg, const Twine &Name = "") { | |||
2547 | return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), | |||
2548 | Name); | |||
2549 | } | |||
2550 | ||||
2551 | /// Return an i1 value testing if \p Arg is not null. | |||
2552 | Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { | |||
2553 | return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), | |||
2554 | Name); | |||
2555 | } | |||
2556 | ||||
2557 | /// Return the i64 difference between two pointer values, dividing out | |||
2558 | /// the size of the pointed-to objects. | |||
2559 | /// | |||
2560 | /// This is intended to implement C-style pointer subtraction. As such, the | |||
2561 | /// pointers must be appropriately aligned for their element types and | |||
2562 | /// pointing into the same object. | |||
2563 | Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
2564 | assert(LHS->getType() == RHS->getType() &&((LHS->getType() == RHS->getType() && "Pointer subtraction operand types must match!" ) ? static_cast<void> (0) : __assert_fail ("LHS->getType() == RHS->getType() && \"Pointer subtraction operand types must match!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2565, __PRETTY_FUNCTION__)) | |||
2565 | "Pointer subtraction operand types must match!")((LHS->getType() == RHS->getType() && "Pointer subtraction operand types must match!" ) ? static_cast<void> (0) : __assert_fail ("LHS->getType() == RHS->getType() && \"Pointer subtraction operand types must match!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2565, __PRETTY_FUNCTION__)); | |||
2566 | auto *ArgType = cast<PointerType>(LHS->getType()); | |||
2567 | Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); | |||
2568 | Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); | |||
2569 | Value *Difference = CreateSub(LHS_int, RHS_int); | |||
2570 | return CreateExactSDiv(Difference, | |||
2571 | ConstantExpr::getSizeOf(ArgType->getElementType()), | |||
2572 | Name); | |||
2573 | } | |||
2574 | ||||
2575 | /// Create a launder.invariant.group intrinsic call. If Ptr type is | |||
2576 | /// different from pointer to i8, it's casted to pointer to i8 in the same | |||
2577 | /// address space before call and casted back to Ptr type after call. | |||
2578 | Value *CreateLaunderInvariantGroup(Value *Ptr) { | |||
2579 | assert(isa<PointerType>(Ptr->getType()) &&((isa<PointerType>(Ptr->getType()) && "launder.invariant.group only applies to pointers." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Ptr->getType()) && \"launder.invariant.group only applies to pointers.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2580, __PRETTY_FUNCTION__)) | |||
2580 | "launder.invariant.group only applies to pointers.")((isa<PointerType>(Ptr->getType()) && "launder.invariant.group only applies to pointers." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Ptr->getType()) && \"launder.invariant.group only applies to pointers.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2580, __PRETTY_FUNCTION__)); | |||
2581 | // FIXME: we could potentially avoid casts to/from i8*. | |||
2582 | auto *PtrType = Ptr->getType(); | |||
2583 | auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace()); | |||
2584 | if (PtrType != Int8PtrTy) | |||
2585 | Ptr = CreateBitCast(Ptr, Int8PtrTy); | |||
2586 | Module *M = BB->getParent()->getParent(); | |||
2587 | Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration( | |||
2588 | M, Intrinsic::launder_invariant_group, {Int8PtrTy}); | |||
2589 | ||||
2590 | assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy &&((FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "LaunderInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"LaunderInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2593, __PRETTY_FUNCTION__)) | |||
2591 | FnLaunderInvariantGroup->getFunctionType()->getParamType(0) ==((FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "LaunderInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"LaunderInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2593, __PRETTY_FUNCTION__)) | |||
2592 | Int8PtrTy &&((FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "LaunderInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"LaunderInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2593, __PRETTY_FUNCTION__)) | |||
2593 | "LaunderInvariantGroup should take and return the same type")((FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "LaunderInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"LaunderInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2593, __PRETTY_FUNCTION__)); | |||
2594 | ||||
2595 | CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr}); | |||
2596 | ||||
2597 | if (PtrType != Int8PtrTy) | |||
2598 | return CreateBitCast(Fn, PtrType); | |||
2599 | return Fn; | |||
2600 | } | |||
2601 | ||||
2602 | /// \brief Create a strip.invariant.group intrinsic call. If Ptr type is | |||
2603 | /// different from pointer to i8, it's casted to pointer to i8 in the same | |||
2604 | /// address space before call and casted back to Ptr type after call. | |||
2605 | Value *CreateStripInvariantGroup(Value *Ptr) { | |||
2606 | assert(isa<PointerType>(Ptr->getType()) &&((isa<PointerType>(Ptr->getType()) && "strip.invariant.group only applies to pointers." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Ptr->getType()) && \"strip.invariant.group only applies to pointers.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2607, __PRETTY_FUNCTION__)) | |||
2607 | "strip.invariant.group only applies to pointers.")((isa<PointerType>(Ptr->getType()) && "strip.invariant.group only applies to pointers." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Ptr->getType()) && \"strip.invariant.group only applies to pointers.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2607, __PRETTY_FUNCTION__)); | |||
2608 | ||||
2609 | // FIXME: we could potentially avoid casts to/from i8*. | |||
2610 | auto *PtrType = Ptr->getType(); | |||
2611 | auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace()); | |||
2612 | if (PtrType != Int8PtrTy) | |||
2613 | Ptr = CreateBitCast(Ptr, Int8PtrTy); | |||
2614 | Module *M = BB->getParent()->getParent(); | |||
2615 | Function *FnStripInvariantGroup = Intrinsic::getDeclaration( | |||
2616 | M, Intrinsic::strip_invariant_group, {Int8PtrTy}); | |||
2617 | ||||
2618 | assert(FnStripInvariantGroup->getReturnType() == Int8PtrTy &&((FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "StripInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"StripInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2621, __PRETTY_FUNCTION__)) | |||
2619 | FnStripInvariantGroup->getFunctionType()->getParamType(0) ==((FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "StripInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"StripInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2621, __PRETTY_FUNCTION__)) | |||
2620 | Int8PtrTy &&((FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "StripInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"StripInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2621, __PRETTY_FUNCTION__)) | |||
2621 | "StripInvariantGroup should take and return the same type")((FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType (0) == Int8PtrTy && "StripInvariantGroup should take and return the same type" ) ? static_cast<void> (0) : __assert_fail ("FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && \"StripInvariantGroup should take and return the same type\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2621, __PRETTY_FUNCTION__)); | |||
2622 | ||||
2623 | CallInst *Fn = CreateCall(FnStripInvariantGroup, {Ptr}); | |||
2624 | ||||
2625 | if (PtrType != Int8PtrTy) | |||
2626 | return CreateBitCast(Fn, PtrType); | |||
2627 | return Fn; | |||
2628 | } | |||
2629 | ||||
2630 | /// Return a vector value that contains \arg V broadcasted to \p | |||
2631 | /// NumElts elements. | |||
2632 | Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") { | |||
2633 | assert(NumElts > 0 && "Cannot splat to an empty vector!")((NumElts > 0 && "Cannot splat to an empty vector!" ) ? static_cast<void> (0) : __assert_fail ("NumElts > 0 && \"Cannot splat to an empty vector!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2633, __PRETTY_FUNCTION__)); | |||
2634 | ||||
2635 | // First insert it into an undef vector so we can shuffle it. | |||
2636 | Type *I32Ty = getInt32Ty(); | |||
2637 | Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts)); | |||
2638 | V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0), | |||
2639 | Name + ".splatinsert"); | |||
2640 | ||||
2641 | // Shuffle the value across the desired number of elements. | |||
2642 | Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts)); | |||
2643 | return CreateShuffleVector(V, Undef, Zeros, Name + ".splat"); | |||
2644 | } | |||
2645 | ||||
2646 | /// Return a value that has been extracted from a larger integer type. | |||
2647 | Value *CreateExtractInteger(const DataLayout &DL, Value *From, | |||
2648 | IntegerType *ExtractedTy, uint64_t Offset, | |||
2649 | const Twine &Name) { | |||
2650 | auto *IntTy = cast<IntegerType>(From->getType()); | |||
2651 | assert(DL.getTypeStoreSize(ExtractedTy) + Offset <=((DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize (IntTy) && "Element extends past full value") ? static_cast <void> (0) : __assert_fail ("DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize(IntTy) && \"Element extends past full value\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2653, __PRETTY_FUNCTION__)) | |||
2652 | DL.getTypeStoreSize(IntTy) &&((DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize (IntTy) && "Element extends past full value") ? static_cast <void> (0) : __assert_fail ("DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize(IntTy) && \"Element extends past full value\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2653, __PRETTY_FUNCTION__)) | |||
2653 | "Element extends past full value")((DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize (IntTy) && "Element extends past full value") ? static_cast <void> (0) : __assert_fail ("DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize(IntTy) && \"Element extends past full value\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2653, __PRETTY_FUNCTION__)); | |||
2654 | uint64_t ShAmt = 8 * Offset; | |||
2655 | Value *V = From; | |||
2656 | if (DL.isBigEndian()) | |||
2657 | ShAmt = 8 * (DL.getTypeStoreSize(IntTy) - | |||
2658 | DL.getTypeStoreSize(ExtractedTy) - Offset); | |||
2659 | if (ShAmt) { | |||
2660 | V = CreateLShr(V, ShAmt, Name + ".shift"); | |||
2661 | } | |||
2662 | assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() &&((ExtractedTy->getBitWidth() <= IntTy->getBitWidth() && "Cannot extract to a larger integer!") ? static_cast <void> (0) : __assert_fail ("ExtractedTy->getBitWidth() <= IntTy->getBitWidth() && \"Cannot extract to a larger integer!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2663, __PRETTY_FUNCTION__)) | |||
2663 | "Cannot extract to a larger integer!")((ExtractedTy->getBitWidth() <= IntTy->getBitWidth() && "Cannot extract to a larger integer!") ? static_cast <void> (0) : __assert_fail ("ExtractedTy->getBitWidth() <= IntTy->getBitWidth() && \"Cannot extract to a larger integer!\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2663, __PRETTY_FUNCTION__)); | |||
2664 | if (ExtractedTy != IntTy) { | |||
2665 | V = CreateTrunc(V, ExtractedTy, Name + ".trunc"); | |||
2666 | } | |||
2667 | return V; | |||
2668 | } | |||
2669 | ||||
2670 | Value *CreatePreserveArrayAccessIndex(Type *ElTy, Value *Base, | |||
2671 | unsigned Dimension, unsigned LastIndex, | |||
2672 | MDNode *DbgInfo) { | |||
2673 | assert(isa<PointerType>(Base->getType()) &&((isa<PointerType>(Base->getType()) && "Invalid Base ptr type for preserve.array.access.index." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Base->getType()) && \"Invalid Base ptr type for preserve.array.access.index.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2674, __PRETTY_FUNCTION__)) | |||
2674 | "Invalid Base ptr type for preserve.array.access.index.")((isa<PointerType>(Base->getType()) && "Invalid Base ptr type for preserve.array.access.index." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Base->getType()) && \"Invalid Base ptr type for preserve.array.access.index.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2674, __PRETTY_FUNCTION__)); | |||
2675 | auto *BaseType = Base->getType(); | |||
2676 | ||||
2677 | Value *LastIndexV = getInt32(LastIndex); | |||
2678 | Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); | |||
2679 | SmallVector<Value *, 4> IdxList; | |||
2680 | for (unsigned I = 0; I < Dimension; ++I) | |||
2681 | IdxList.push_back(Zero); | |||
2682 | IdxList.push_back(LastIndexV); | |||
2683 | ||||
2684 | Type *ResultType = | |||
2685 | GetElementPtrInst::getGEPReturnType(ElTy, Base, IdxList); | |||
2686 | ||||
2687 | Module *M = BB->getParent()->getParent(); | |||
2688 | Function *FnPreserveArrayAccessIndex = Intrinsic::getDeclaration( | |||
2689 | M, Intrinsic::preserve_array_access_index, {ResultType, BaseType}); | |||
2690 | ||||
2691 | Value *DimV = getInt32(Dimension); | |||
2692 | CallInst *Fn = | |||
2693 | CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV}); | |||
2694 | if (DbgInfo) | |||
2695 | Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); | |||
2696 | ||||
2697 | return Fn; | |||
2698 | } | |||
2699 | ||||
2700 | Value *CreatePreserveUnionAccessIndex(Value *Base, unsigned FieldIndex, | |||
2701 | MDNode *DbgInfo) { | |||
2702 | assert(isa<PointerType>(Base->getType()) &&((isa<PointerType>(Base->getType()) && "Invalid Base ptr type for preserve.union.access.index." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Base->getType()) && \"Invalid Base ptr type for preserve.union.access.index.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2703, __PRETTY_FUNCTION__)) | |||
2703 | "Invalid Base ptr type for preserve.union.access.index.")((isa<PointerType>(Base->getType()) && "Invalid Base ptr type for preserve.union.access.index." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Base->getType()) && \"Invalid Base ptr type for preserve.union.access.index.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2703, __PRETTY_FUNCTION__)); | |||
2704 | auto *BaseType = Base->getType(); | |||
2705 | ||||
2706 | Module *M = BB->getParent()->getParent(); | |||
2707 | Function *FnPreserveUnionAccessIndex = Intrinsic::getDeclaration( | |||
2708 | M, Intrinsic::preserve_union_access_index, {BaseType, BaseType}); | |||
2709 | ||||
2710 | Value *DIIndex = getInt32(FieldIndex); | |||
2711 | CallInst *Fn = | |||
2712 | CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex}); | |||
2713 | if (DbgInfo) | |||
2714 | Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); | |||
2715 | ||||
2716 | return Fn; | |||
2717 | } | |||
2718 | ||||
2719 | Value *CreatePreserveStructAccessIndex(Type *ElTy, Value *Base, | |||
2720 | unsigned Index, unsigned FieldIndex, | |||
2721 | MDNode *DbgInfo) { | |||
2722 | assert(isa<PointerType>(Base->getType()) &&((isa<PointerType>(Base->getType()) && "Invalid Base ptr type for preserve.struct.access.index." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Base->getType()) && \"Invalid Base ptr type for preserve.struct.access.index.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2723, __PRETTY_FUNCTION__)) | |||
2723 | "Invalid Base ptr type for preserve.struct.access.index.")((isa<PointerType>(Base->getType()) && "Invalid Base ptr type for preserve.struct.access.index." ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(Base->getType()) && \"Invalid Base ptr type for preserve.struct.access.index.\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2723, __PRETTY_FUNCTION__)); | |||
2724 | auto *BaseType = Base->getType(); | |||
2725 | ||||
2726 | Value *GEPIndex = getInt32(Index); | |||
2727 | Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); | |||
2728 | Type *ResultType = | |||
2729 | GetElementPtrInst::getGEPReturnType(ElTy, Base, {Zero, GEPIndex}); | |||
2730 | ||||
2731 | Module *M = BB->getParent()->getParent(); | |||
2732 | Function *FnPreserveStructAccessIndex = Intrinsic::getDeclaration( | |||
2733 | M, Intrinsic::preserve_struct_access_index, {ResultType, BaseType}); | |||
2734 | ||||
2735 | Value *DIIndex = getInt32(FieldIndex); | |||
2736 | CallInst *Fn = CreateCall(FnPreserveStructAccessIndex, | |||
2737 | {Base, GEPIndex, DIIndex}); | |||
2738 | if (DbgInfo) | |||
2739 | Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); | |||
2740 | ||||
2741 | return Fn; | |||
2742 | } | |||
2743 | ||||
2744 | private: | |||
2745 | /// Helper function that creates an assume intrinsic call that | |||
2746 | /// represents an alignment assumption on the provided Ptr, Mask, Type | |||
2747 | /// and Offset. It may be sometimes useful to do some other logic | |||
2748 | /// based on this alignment check, thus it can be stored into 'TheCheck'. | |||
2749 | CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL, | |||
2750 | Value *PtrValue, Value *Mask, | |||
2751 | Type *IntPtrTy, Value *OffsetValue, | |||
2752 | Value **TheCheck) { | |||
2753 | Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint"); | |||
2754 | ||||
2755 | if (OffsetValue) { | |||
2756 | bool IsOffsetZero = false; | |||
2757 | if (const auto *CI = dyn_cast<ConstantInt>(OffsetValue)) | |||
2758 | IsOffsetZero = CI->isZero(); | |||
2759 | ||||
2760 | if (!IsOffsetZero) { | |||
2761 | if (OffsetValue->getType() != IntPtrTy) | |||
2762 | OffsetValue = CreateIntCast(OffsetValue, IntPtrTy, /*isSigned*/ true, | |||
2763 | "offsetcast"); | |||
2764 | PtrIntValue = CreateSub(PtrIntValue, OffsetValue, "offsetptr"); | |||
2765 | } | |||
2766 | } | |||
2767 | ||||
2768 | Value *Zero = ConstantInt::get(IntPtrTy, 0); | |||
2769 | Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr"); | |||
2770 | Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond"); | |||
2771 | if (TheCheck) | |||
2772 | *TheCheck = InvCond; | |||
2773 | ||||
2774 | return CreateAssumption(InvCond); | |||
2775 | } | |||
2776 | ||||
2777 | public: | |||
2778 | /// Create an assume intrinsic call that represents an alignment | |||
2779 | /// assumption on the provided pointer. | |||
2780 | /// | |||
2781 | /// An optional offset can be provided, and if it is provided, the offset | |||
2782 | /// must be subtracted from the provided pointer to get the pointer with the | |||
2783 | /// specified alignment. | |||
2784 | /// | |||
2785 | /// It may be sometimes useful to do some other logic | |||
2786 | /// based on this alignment check, thus it can be stored into 'TheCheck'. | |||
2787 | CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, | |||
2788 | unsigned Alignment, | |||
2789 | Value *OffsetValue = nullptr, | |||
2790 | Value **TheCheck = nullptr) { | |||
2791 | assert(isa<PointerType>(PtrValue->getType()) &&((isa<PointerType>(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?" ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(PtrValue->getType()) && \"trying to create an alignment assumption on a non-pointer?\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2792, __PRETTY_FUNCTION__)) | |||
2792 | "trying to create an alignment assumption on a non-pointer?")((isa<PointerType>(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?" ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(PtrValue->getType()) && \"trying to create an alignment assumption on a non-pointer?\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2792, __PRETTY_FUNCTION__)); | |||
2793 | assert(Alignment != 0 && "Invalid Alignment")((Alignment != 0 && "Invalid Alignment") ? static_cast <void> (0) : __assert_fail ("Alignment != 0 && \"Invalid Alignment\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2793, __PRETTY_FUNCTION__)); | |||
2794 | auto *PtrTy = cast<PointerType>(PtrValue->getType()); | |||
2795 | Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); | |||
2796 | ||||
2797 | Value *Mask = ConstantInt::get(IntPtrTy, Alignment - 1); | |||
2798 | return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, | |||
2799 | OffsetValue, TheCheck); | |||
2800 | } | |||
2801 | ||||
2802 | /// Create an assume intrinsic call that represents an alignment | |||
2803 | /// assumption on the provided pointer. | |||
2804 | /// | |||
2805 | /// An optional offset can be provided, and if it is provided, the offset | |||
2806 | /// must be subtracted from the provided pointer to get the pointer with the | |||
2807 | /// specified alignment. | |||
2808 | /// | |||
2809 | /// It may be sometimes useful to do some other logic | |||
2810 | /// based on this alignment check, thus it can be stored into 'TheCheck'. | |||
2811 | /// | |||
2812 | /// This overload handles the condition where the Alignment is dependent | |||
2813 | /// on an existing value rather than a static value. | |||
2814 | CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, | |||
2815 | Value *Alignment, | |||
2816 | Value *OffsetValue = nullptr, | |||
2817 | Value **TheCheck = nullptr) { | |||
2818 | assert(isa<PointerType>(PtrValue->getType()) &&((isa<PointerType>(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?" ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(PtrValue->getType()) && \"trying to create an alignment assumption on a non-pointer?\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2819, __PRETTY_FUNCTION__)) | |||
2819 | "trying to create an alignment assumption on a non-pointer?")((isa<PointerType>(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?" ) ? static_cast<void> (0) : __assert_fail ("isa<PointerType>(PtrValue->getType()) && \"trying to create an alignment assumption on a non-pointer?\"" , "/build/llvm-toolchain-snapshot-10~++20200109111124+f0abe820eeb/llvm/include/llvm/IR/IRBuilder.h" , 2819, __PRETTY_FUNCTION__)); | |||
2820 | auto *PtrTy = cast<PointerType>(PtrValue->getType()); | |||
2821 | Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); | |||
2822 | ||||
2823 | if (Alignment->getType() != IntPtrTy) | |||
2824 | Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ false, | |||
2825 | "alignmentcast"); | |||
2826 | ||||
2827 | Value *Mask = CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "mask"); | |||
2828 | ||||
2829 | return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, | |||
2830 | OffsetValue, TheCheck); | |||
2831 | } | |||
2832 | }; | |||
2833 | ||||
2834 | // Create wrappers for C Binding types (see CBindingWrapping.h). | |||
2835 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)inline IRBuilder<> *unwrap(LLVMBuilderRef P) { return reinterpret_cast <IRBuilder<>*>(P); } inline LLVMBuilderRef wrap(const IRBuilder<> *P) { return reinterpret_cast<LLVMBuilderRef >(const_cast<IRBuilder<>*>(P)); } | |||
2836 | ||||
2837 | } // end namespace llvm | |||
2838 | ||||
2839 | #endif // LLVM_IR_IRBUILDER_H |