29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/StringMap.h"
31 #include "llvm/IR/CallSite.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"
38 using namespace clang;
39 using namespace CodeGen;
45 class LazyRuntimeFunction {
47 llvm::FunctionType *FTy;
48 const char *FunctionName;
56 : CGM(nullptr), FunctionName(nullptr),
Function(nullptr) {}
60 template <
typename... Tys>
68 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71 FTy = llvm::FunctionType::get(RetTy, None,
false);
75 llvm::FunctionType *getType() {
return FTy; }
79 operator llvm::Constant *() {
84 cast<llvm::Constant>(CGM->CreateRuntimeFunction(FTy, FunctionName));
88 operator llvm::Function *() {
89 return cast<llvm::Function>((llvm::Constant *)*
this);
100 llvm::Module &TheModule;
103 llvm::StructType *ObjCSuperTy;
106 llvm::PointerType *PtrToObjCSuperTy;
110 llvm::PointerType *SelectorTy;
113 llvm::IntegerType *Int8Ty;
116 llvm::PointerType *PtrToInt8Ty;
122 llvm::PointerType *IMPTy;
127 llvm::PointerType *IdTy;
130 llvm::PointerType *PtrToIdTy;
135 llvm::IntegerType *IntTy;
139 llvm::PointerType *PtrTy;
143 llvm::IntegerType *LongTy;
145 llvm::IntegerType *SizeTy;
147 llvm::IntegerType *IntPtrTy;
149 llvm::IntegerType *PtrDiffTy;
152 llvm::PointerType *PtrToIntTy;
156 llvm::IntegerType *Int32Ty;
158 llvm::IntegerType *Int64Ty;
162 unsigned msgSendMDKind;
167 llvm::Constant *MakeConstantString(StringRef Str,
const char *
Name =
"") {
169 return llvm::ConstantExpr::getGetElementPtr(Array.
getElementType(),
177 llvm::Constant *ExportUniqueString(
const std::string &Str, StringRef Prefix) {
178 std::string
Name = Prefix.str() + Str;
179 auto *ConstStr = TheModule.getGlobalVariable(Name);
181 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
182 ConstStr =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
183 llvm::GlobalValue::LinkOnceODRLinkage,
186 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
193 llvm::GlobalVariable *MakeGlobal(llvm::Constant *C,
196 llvm::GlobalValue::LinkageTypes linkage
198 auto GV =
new llvm::GlobalVariable(TheModule, C->getType(),
false,
206 const Decl *Container) {
210 std::string NameAndAttributes;
211 std::string TypeStr =
212 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
213 NameAndAttributes +=
'\0';
214 NameAndAttributes += TypeStr.length() + 3;
215 NameAndAttributes += TypeStr;
216 NameAndAttributes +=
'\0';
218 return MakeConstantString(NameAndAttributes);
227 int attrs =
property->getPropertyAttributes();
236 Fields.
addInt(Int8Ty, attrs & 0xff);
242 attrs |= isSynthesized ? (1<<0) : 0;
246 Fields.
addInt(Int8Ty, attrs & 0xff);
256 if (V->getType() == Ty)
return V;
260 if (V.
getType() == Ty)
return V;
265 llvm::Constant *Zeros[2];
267 llvm::Constant *NULLPtr;
269 llvm::LLVMContext &VMContext;
276 llvm::GlobalAlias *ClassPtrAlias;
281 llvm::GlobalAlias *MetaClassPtrAlias;
283 std::vector<llvm::Constant*> Classes;
285 std::vector<llvm::Constant*> Categories;
288 std::vector<llvm::Constant*> ConstantStrings;
292 llvm::StringMap<llvm::Constant*> ObjCStrings;
294 llvm::StringMap<llvm::Constant*> ExistingProtocols;
300 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
304 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
312 Selector RetainSel, ReleaseSel, AutoreleaseSel;
316 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
317 WeakAssignFn, GlobalAssignFn;
319 typedef std::pair<std::string, std::string> ClassAliasPair;
321 std::vector<ClassAliasPair> ClassAliases;
325 LazyRuntimeFunction ExceptionThrowFn;
328 LazyRuntimeFunction ExceptionReThrowFn;
331 LazyRuntimeFunction EnterCatchFn;
334 LazyRuntimeFunction ExitCatchFn;
336 LazyRuntimeFunction SyncEnterFn;
338 LazyRuntimeFunction SyncExitFn;
343 LazyRuntimeFunction EnumerationMutationFn;
346 LazyRuntimeFunction GetPropertyFn;
349 LazyRuntimeFunction SetPropertyFn;
351 LazyRuntimeFunction GetStructPropertyFn;
353 LazyRuntimeFunction SetStructPropertyFn;
364 const int ProtocolVersion;
379 llvm::Constant *GenerateMethodList(StringRef ClassName,
380 StringRef CategoryName,
383 bool isClassMethodList);
388 llvm::Constant *GenerateEmptyProtocol(
const std::string &ProtocolName);
404 void GenerateProtocolHolderCategory();
407 llvm::Constant *GenerateClassStructure(
408 llvm::Constant *MetaClass,
409 llvm::Constant *SuperClass,
412 llvm::Constant *Version,
413 llvm::Constant *InstanceSize,
414 llvm::Constant *IVars,
415 llvm::Constant *Methods,
416 llvm::Constant *Protocols,
417 llvm::Constant *IvarOffsets,
418 llvm::Constant *Properties,
419 llvm::Constant *StrongIvarBitmap,
420 llvm::Constant *WeakIvarBitmap,
425 llvm::Constant *GenerateProtocolMethodList(
432 const std::string &TypeEncoding);
441 void EmitClassRef(
const std::string &className);
445 const std::string &Name,
bool isWeak);
454 MessageSendInfo &MSI) = 0;
462 MessageSendInfo &MSI) = 0;
479 unsigned protocolClassVersion);
502 llvm::Constant *GetEHType(
QualType T)
override;
512 llvm::Function *ModuleInitFunction()
override;
513 llvm::Constant *GetPropertyGetFunction()
override;
514 llvm::Constant *GetPropertySetFunction()
override;
515 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
517 llvm::Constant *GetSetStructFunction()
override;
518 llvm::Constant *GetGetStructFunction()
override;
519 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
520 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
521 llvm::Constant *EnumerationMutationFunction()
override;
529 bool ClearInsertionPoint=
true)
override;
536 bool threadlocal=
false)
override;
546 unsigned CVRQualifiers)
override;
573 class CGObjCGCC :
public CGObjCGNU {
576 LazyRuntimeFunction MsgLookupFn;
580 LazyRuntimeFunction MsgLookupSuperFn;
585 MessageSendInfo &MSI)
override {
588 EnforceType(Builder, Receiver, IdTy),
589 EnforceType(Builder, cmd, SelectorTy) };
591 imp->setMetadata(msgSendMDKind, node);
592 return imp.getInstruction();
598 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
599 PtrToObjCSuperTy).getPointer(), cmd};
606 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
608 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
609 PtrToObjCSuperTy, SelectorTy);
614 class CGObjCGNUstep :
public CGObjCGNU {
617 LazyRuntimeFunction SlotLookupFn;
622 LazyRuntimeFunction SlotLookupSuperFn;
624 LazyRuntimeFunction SetPropertyAtomic;
626 LazyRuntimeFunction SetPropertyAtomicCopy;
628 LazyRuntimeFunction SetPropertyNonAtomic;
630 LazyRuntimeFunction SetPropertyNonAtomicCopy;
633 LazyRuntimeFunction CxxAtomicObjectGetFn;
636 LazyRuntimeFunction CxxAtomicObjectSetFn;
642 llvm::Constant *GetEHType(
QualType T)
override;
647 MessageSendInfo &MSI)
override {
649 llvm::Function *LookupFn = SlotLookupFn;
661 self = llvm::ConstantPointerNull::get(IdTy);
665 LookupFn->addParamAttr(0, llvm::Attribute::NoCapture);
668 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
669 EnforceType(Builder, cmd, SelectorTy),
670 EnforceType(Builder,
self, IdTy) };
672 slot.setOnlyReadsMemory();
673 slot->setMetadata(msgSendMDKind, node);
682 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
688 MessageSendInfo &MSI)
override {
692 llvm::CallInst *slot =
694 slot->setOnlyReadsMemory();
704 llvm::StructType *SlotStructTy =
705 llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
706 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
708 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
711 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
712 PtrToObjCSuperTy, SelectorTy);
714 if (CGM.getLangOpts().CPlusPlus) {
715 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
717 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
719 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
721 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
724 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
726 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
728 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
730 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
732 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
733 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
734 SelectorTy, IdTy, PtrDiffTy);
735 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
736 IdTy, SelectorTy, IdTy, PtrDiffTy);
737 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
738 IdTy, SelectorTy, IdTy, PtrDiffTy);
739 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
740 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
743 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
747 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
751 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
754 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
756 return CxxAtomicObjectGetFn;
759 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
762 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
764 return CxxAtomicObjectSetFn;
767 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
768 bool copy)
override {
775 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
779 if (copy)
return SetPropertyAtomicCopy;
780 return SetPropertyAtomic;
783 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
788 class CGObjCObjFW:
public CGObjCGNU {
792 LazyRuntimeFunction MsgLookupFn;
795 LazyRuntimeFunction MsgLookupFnSRet;
799 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
803 MessageSendInfo &MSI)
override {
806 EnforceType(Builder, Receiver, IdTy),
807 EnforceType(Builder, cmd, SelectorTy) };
810 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
815 imp->setMetadata(msgSendMDKind, node);
816 return imp.getInstruction();
823 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
826 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
833 bool isWeak)
override {
835 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
838 std::string SymbolName =
"_OBJC_CLASS_" +
Name;
839 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
841 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
843 nullptr, SymbolName);
850 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
851 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
854 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
855 PtrToObjCSuperTy, SelectorTy);
856 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
857 PtrToObjCSuperTy, SelectorTy);
865 void CGObjCGNU::EmitClassRef(
const std::string &className) {
866 std::string symbolRef =
"__objc_class_ref_" + className;
868 if (TheModule.getGlobalVariable(symbolRef))
870 std::string symbolName =
"__objc_class_name_" + className;
871 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
873 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
875 nullptr, symbolName);
877 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
878 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
882 StringRef CategoryName,
const Selector MethodName,
883 bool isClassMethod) {
884 std::string MethodNameColonStripped = MethodName.
getAsString();
885 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
887 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
888 CategoryName +
"_" + MethodNameColonStripped).str();
891 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
892 unsigned protocolClassVersion)
894 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
895 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
896 ProtocolVersion(protocolClassVersion) {
898 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
901 IntTy = cast<llvm::IntegerType>(
903 LongTy = cast<llvm::IntegerType>(
905 SizeTy = cast<llvm::IntegerType>(
906 Types.
ConvertType(CGM.getContext().getSizeType()));
907 PtrDiffTy = cast<llvm::IntegerType>(
908 Types.
ConvertType(CGM.getContext().getPointerDiffType()));
909 BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
911 Int8Ty = llvm::Type::getInt8Ty(VMContext);
913 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
915 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
917 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
919 QualType selTy = CGM.getContext().getObjCSelType();
921 SelectorTy = PtrToInt8Ty;
923 SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
926 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
929 Int32Ty = llvm::Type::getInt32Ty(VMContext);
930 Int64Ty = llvm::Type::getInt64Ty(VMContext);
933 CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
936 QualType UnqualIdTy = CGM.getContext().getObjCIdType();
939 ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy);
940 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
944 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
946 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
947 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
949 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
952 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
953 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
955 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
957 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
960 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
963 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
966 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
967 PtrDiffTy, IdTy, BoolTy, BoolTy);
969 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
970 PtrDiffTy, BoolTy, BoolTy);
972 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
973 PtrDiffTy, BoolTy, BoolTy);
976 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
977 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
981 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
985 if (Opts.getGC() != LangOptions::NonGC) {
997 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
999 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
1002 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
1004 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
1006 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
1008 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
1014 const std::string &Name,
bool isWeak) {
1015 llvm::Constant *ClassName = MakeConstantString(Name);
1026 llvm::Constant *ClassLookupFn =
1027 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
1028 "objc_lookup_class");
1038 if (CGM.getTriple().isOSBinFormatCOFF()) {
1039 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
1040 auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
1041 if (OID->
hasAttr<DLLExportAttr>())
1042 DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
1043 else if (OID->
hasAttr<DLLImportAttr>())
1044 DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
1045 ClassSymbol->setDLLStorageClass(DLLStorage);
1052 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
1053 if (CGM.getTriple().isOSBinFormatCOFF()) {
1054 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
1057 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
1061 if ((VD = dyn_cast<VarDecl>(
Result)))
1064 auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
1065 if (!VD || VD->
hasAttr<DLLImportAttr>())
1066 DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
1067 else if (VD->
hasAttr<DLLExportAttr>())
1068 DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
1070 ClassSymbol->setDLLStorageClass(DLLStorage);
1077 const std::string &TypeEncoding) {
1079 llvm::GlobalAlias *SelValue =
nullptr;
1082 e = Types.end() ; i!=e ; i++) {
1083 if (i->first == TypeEncoding) {
1084 SelValue = i->second;
1090 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
1091 ".objc_selector_" + Sel.
getAsString(), &TheModule);
1092 Types.emplace_back(TypeEncoding, SelValue);
1110 return GetSelector(CGF, Sel, std::string());
1115 std::string SelTypes = CGM.getContext().getObjCEncodingForMethodDecl(Method);
1116 return GetSelector(CGF, Method->
getSelector(), SelTypes);
1119 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
1125 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
1126 return MakeConstantString(
"@id");
1134 assert(OPT &&
"Invalid @catch type.");
1136 assert(IDecl &&
"Invalid @catch type.");
1140 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
1141 if (!CGM.getLangOpts().CPlusPlus)
1142 return CGObjCGNU::GetEHType(T);
1150 llvm::Constant *IDEHType =
1151 CGM.getModule().getGlobalVariable(
"__objc_id_type_info");
1154 new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
1157 nullptr,
"__objc_id_type_info");
1158 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
1163 assert(PT &&
"Invalid @catch type.");
1165 assert(IT &&
"Invalid @catch type.");
1168 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
1171 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
1173 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
1180 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
1181 auto *Vtable = TheModule.getGlobalVariable(vtableName);
1183 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
1185 nullptr, vtableName);
1187 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
1188 auto *BVtable = llvm::ConstantExpr::getBitCast(
1189 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
1192 llvm::Constant *typeName =
1193 ExportUniqueString(className,
"__objc_eh_typename_");
1196 auto fields = builder.beginStruct();
1197 fields.add(BVtable);
1198 fields.add(typeName);
1199 llvm::Constant *TI =
1200 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
1201 CGM.getPointerAlign(),
1203 llvm::GlobalValue::LinkOnceODRLinkage);
1204 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
1210 std::string Str = SL->
getString().str();
1211 CharUnits Align = CGM.getPointerAlign();
1214 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
1215 if (old != ObjCStrings.end())
1218 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1220 if (StringClass.empty()) StringClass =
"NXConstantString";
1222 std::string Sym =
"_OBJC_CLASS_";
1225 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1228 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1229 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
1230 else if (isa->getType() != PtrToIdTy)
1231 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1234 auto Fields = Builder.beginStruct();
1236 Fields.
add(MakeConstantString(Str));
1237 Fields.
addInt(IntTy, Str.size());
1238 llvm::Constant *ObjCStr =
1240 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
1241 ObjCStrings[Str] = ObjCStr;
1242 ConstantStrings.push_back(ObjCStr);
1255 bool isCategoryImpl,
1257 bool IsClassMessage,
1261 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1262 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1263 return RValue::get(EnforceType(Builder, Receiver,
1264 CGM.getTypes().ConvertType(ResultType)));
1266 if (Sel == ReleaseSel) {
1267 return RValue::get(
nullptr);
1274 ActualArgs.
add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
1278 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1281 if (isCategoryImpl) {
1282 llvm::Constant *classLookupFunction =
nullptr;
1283 if (IsClassMessage) {
1284 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1285 IdTy, PtrTy,
true),
"objc_get_meta_class");
1287 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1288 IdTy, PtrTy,
true),
"objc_get_class");
1290 ReceiverClass = Builder.CreateCall(classLookupFunction,
1298 if (IsClassMessage) {
1299 if (!MetaClassPtrAlias) {
1304 ReceiverClass = MetaClassPtrAlias;
1306 if (!ClassPtrAlias) {
1311 ReceiverClass = ClassPtrAlias;
1315 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
1317 llvm::PointerType::getUnqual(CastTy));
1324 llvm::StructType *ObjCSuperTy =
1325 llvm::StructType::get(Receiver->getType(), IdTy);
1336 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
1339 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
1340 imp = EnforceType(Builder, imp, MSI.MessengerType);
1342 llvm::Metadata *impMD[] = {
1343 llvm::MDString::get(VMContext, Sel.
getAsString()),
1345 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1346 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
1347 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1351 llvm::Instruction *call;
1352 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
1353 call->setMetadata(msgSendMDKind, node);
1370 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1371 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1372 return RValue::get(EnforceType(Builder, Receiver,
1373 CGM.getTypes().ConvertType(ResultType)));
1375 if (Sel == ReleaseSel) {
1376 return RValue::get(
nullptr);
1394 llvm::BasicBlock *startBB =
nullptr;
1395 llvm::BasicBlock *messageBB =
nullptr;
1396 llvm::BasicBlock *continueBB =
nullptr;
1398 if (!isPointerSizedReturn) {
1399 startBB = Builder.GetInsertBlock();
1403 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
1404 llvm::Constant::getNullValue(Receiver->getType()));
1405 Builder.CreateCondBr(isNil, continueBB, messageBB);
1409 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
1412 cmd = GetSelector(CGF, Method);
1414 cmd = GetSelector(CGF, Sel);
1415 cmd = EnforceType(Builder, cmd, SelectorTy);
1416 Receiver = EnforceType(Builder, Receiver, IdTy);
1418 llvm::Metadata *impMD[] = {
1419 llvm::MDString::get(VMContext, Sel.
getAsString()),
1420 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
1421 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1422 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
1423 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1426 ActualArgs.
add(RValue::get(Receiver), ASTIdTy);
1430 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1438 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
1439 case CodeGenOptions::Legacy:
1440 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
1442 case CodeGenOptions::Mixed:
1443 case CodeGenOptions::NonLegacy:
1444 if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1445 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1446 "objc_msgSend_fpret");
1447 }
else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1450 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1451 "objc_msgSend_stret");
1453 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1459 ActualArgs[0] =
CallArg(RValue::get(Receiver), ASTIdTy,
false);
1461 imp = EnforceType(Builder, imp, MSI.MessengerType);
1463 llvm::Instruction *call;
1465 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
1466 call->setMetadata(msgSendMDKind, node);
1469 if (!isPointerSizedReturn) {
1470 messageBB = CGF.
Builder.GetInsertBlock();
1471 CGF.
Builder.CreateBr(continueBB);
1475 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1476 phi->addIncoming(v, messageBB);
1477 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
1478 msgRet = RValue::get(phi);
1481 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
1484 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
1486 phi->addIncoming(NullVal.
getPointer(), startBB);
1489 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
1490 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
1491 phi->addIncoming(v.first, messageBB);
1492 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
1494 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
1495 phi2->addIncoming(v.second, messageBB);
1496 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
1498 msgRet = RValue::getComplex(phi, phi2);
1506 llvm::Constant *CGObjCGNU::
1507 GenerateMethodList(StringRef ClassName,
1508 StringRef CategoryName,
1511 bool isClassMethodList) {
1512 if (MethodSels.empty())
1517 auto MethodList = Builder.beginStruct();
1518 MethodList.addNullPointer(CGM.Int8PtrTy);
1519 MethodList.addInt(Int32Ty, MethodTypes.size());
1522 llvm::StructType *ObjCMethodTy =
1523 llvm::StructType::get(CGM.getLLVMContext(), {
1528 auto Methods = MethodList.beginArray();
1529 for (
unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
1530 llvm::Constant *FnPtr =
1533 isClassMethodList));
1534 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
1535 auto Method = Methods.beginStruct(ObjCMethodTy);
1536 Method.
add(MakeConstantString(MethodSels[i].getAsString()));
1537 Method.
add(MethodTypes[i]);
1538 Method.addBitCast(FnPtr, IMPTy);
1539 Method.finishAndAddTo(Methods);
1541 Methods.finishAndAddTo(MethodList);
1544 return MethodList.finishAndCreateGlobal(
".objc_method_list",
1545 CGM.getPointerAlign());
1549 llvm::Constant *CGObjCGNU::
1553 if (IvarNames.empty())
1559 auto IvarList = Builder.beginStruct();
1560 IvarList.addInt(IntTy, (
int)IvarNames.size());
1563 llvm::StructType *ObjCIvarTy =
1564 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
1567 auto Ivars = IvarList.beginArray(ObjCIvarTy);
1568 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
1569 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
1570 Ivar.add(IvarNames[i]);
1571 Ivar.add(IvarTypes[i]);
1572 Ivar.add(IvarOffsets[i]);
1573 Ivar.finishAndAddTo(Ivars);
1575 Ivars.finishAndAddTo(IvarList);
1578 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
1579 CGM.getPointerAlign());
1583 llvm::Constant *CGObjCGNU::GenerateClassStructure(
1584 llvm::Constant *MetaClass,
1585 llvm::Constant *SuperClass,
1588 llvm::Constant *Version,
1589 llvm::Constant *InstanceSize,
1590 llvm::Constant *IVars,
1591 llvm::Constant *Methods,
1592 llvm::Constant *Protocols,
1593 llvm::Constant *IvarOffsets,
1594 llvm::Constant *Properties,
1595 llvm::Constant *StrongIvarBitmap,
1596 llvm::Constant *WeakIvarBitmap,
1605 llvm::StructType *ClassTy = llvm::StructType::get(
1622 IvarOffsets->getType(),
1623 Properties->getType(),
1629 auto Elements = Builder.beginStruct(ClassTy);
1634 Elements.addBitCast(MetaClass, PtrToInt8Ty);
1636 Elements.add(SuperClass);
1638 Elements.add(MakeConstantString(Name,
".class_name"));
1640 Elements.addInt(LongTy, 0);
1642 Elements.addInt(LongTy, info);
1645 llvm::DataLayout td(&TheModule);
1646 Elements.addInt(LongTy,
1647 td.getTypeSizeInBits(ClassTy) /
1648 CGM.getContext().getCharWidth());
1650 Elements.add(InstanceSize);
1652 Elements.add(IVars);
1654 Elements.add(Methods);
1657 Elements.add(NULLPtr);
1659 Elements.add(NULLPtr);
1661 Elements.add(NULLPtr);
1663 Elements.addBitCast(Protocols, PtrTy);
1665 Elements.add(NULLPtr);
1667 Elements.addInt(LongTy, 1);
1669 Elements.add(IvarOffsets);
1671 Elements.add(Properties);
1673 Elements.add(StrongIvarBitmap);
1675 Elements.add(WeakIvarBitmap);
1680 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
1682 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
1683 llvm::Constant *Class =
1684 Elements.finishAndCreateGlobal(ClassSym, CGM.getPointerAlign(),
false,
1687 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
1688 ClassRef->getType()));
1689 ClassRef->removeFromParent();
1690 Class->setName(ClassSym);
1695 llvm::Constant *CGObjCGNU::
1699 llvm::StructType *ObjCMethodDescTy =
1700 llvm::StructType::get(CGM.getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
1702 auto MethodList = Builder.beginStruct();
1703 MethodList.addInt(IntTy, MethodNames.size());
1704 auto Methods = MethodList.beginArray(ObjCMethodDescTy);
1705 for (
unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
1706 auto Method = Methods.beginStruct(ObjCMethodDescTy);
1707 Method.
add(MethodNames[i]);
1708 Method.
add(MethodTypes[i]);
1709 Method.finishAndAddTo(Methods);
1711 Methods.finishAndAddTo(MethodList);
1712 return MethodList.finishAndCreateGlobal(
".objc_method_list",
1713 CGM.getPointerAlign());
1721 auto ProtocolList = Builder.beginStruct();
1722 ProtocolList.add(NULLPtr);
1723 ProtocolList.addInt(LongTy, Protocols.size());
1725 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
1726 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
1727 iter != endIter ; iter++) {
1728 llvm::Constant *protocol =
nullptr;
1729 llvm::StringMap<llvm::Constant*>::iterator value =
1730 ExistingProtocols.find(*iter);
1731 if (value == ExistingProtocols.end()) {
1732 protocol = GenerateEmptyProtocol(*iter);
1734 protocol = value->getValue();
1736 Elements.addBitCast(protocol, PtrToInt8Ty);
1738 Elements.finishAndAddTo(ProtocolList);
1739 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
1740 CGM.getPointerAlign());
1747 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
1752 CGObjCGNU::GenerateEmptyProtocol(
const std::string &ProtocolName) {
1753 llvm::Constant *ProtocolList = GenerateProtocolList({});
1754 llvm::Constant *MethodList = GenerateProtocolMethodList({}, {});
1758 auto Elements = Builder.beginStruct();
1762 Elements.add(llvm::ConstantExpr::getIntToPtr(
1763 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1765 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
1766 Elements.add(ProtocolList);
1767 Elements.add(MethodList);
1768 Elements.add(MethodList);
1769 Elements.add(MethodList);
1770 Elements.add(MethodList);
1771 return Elements.finishAndCreateGlobal(
".objc_protocol",
1772 CGM.getPointerAlign());
1785 Protocols.push_back(PI->getNameAsString());
1792 if (
I->getImplementationControl() == ObjCMethodDecl::Optional) {
1793 OptionalInstanceMethodNames.push_back(
1794 MakeConstantString(
I->getSelector().getAsString()));
1795 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1797 InstanceMethodNames.push_back(
1798 MakeConstantString(
I->getSelector().getAsString()));
1799 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1809 if (
I->getImplementationControl() == ObjCMethodDecl::Optional) {
1810 OptionalClassMethodNames.push_back(
1811 MakeConstantString(
I->getSelector().getAsString()));
1812 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1814 ClassMethodNames.push_back(
1815 MakeConstantString(
I->getSelector().getAsString()));
1816 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1820 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1821 llvm::Constant *InstanceMethodList =
1822 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1823 llvm::Constant *ClassMethodList =
1824 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1825 llvm::Constant *OptionalInstanceMethodList =
1826 GenerateProtocolMethodList(OptionalInstanceMethodNames,
1827 OptionalInstanceMethodTypes);
1828 llvm::Constant *OptionalClassMethodList =
1829 GenerateProtocolMethodList(OptionalClassMethodNames,
1830 OptionalClassMethodTypes);
1838 llvm::Constant *PropertyList;
1839 llvm::Constant *OptionalPropertyList;
1841 llvm::StructType *propertyMetadataTy =
1842 llvm::StructType::get(CGM.getLLVMContext(),
1843 { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
1844 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
1846 unsigned numReqProperties = 0, numOptProperties = 0;
1855 auto reqPropertiesList = reqPropertyListBuilder.beginStruct();
1856 reqPropertiesList.addInt(IntTy, numReqProperties);
1857 reqPropertiesList.add(NULLPtr);
1858 auto reqPropertiesArray = reqPropertiesList.beginArray(propertyMetadataTy);
1861 auto optPropertiesList = optPropertyListBuilder.beginStruct();
1862 optPropertiesList.addInt(IntTy, numOptProperties);
1863 optPropertiesList.add(NULLPtr);
1864 auto optPropertiesArray = optPropertiesList.beginArray(propertyMetadataTy);
1869 auto &propertiesArray =
1870 (
property->isOptional() ? optPropertiesArray : reqPropertiesArray);
1871 auto fields = propertiesArray.beginStruct(propertyMetadataTy);
1873 fields.add(MakePropertyEncodingString(property,
nullptr));
1874 PushPropertyAttributes(fields, property);
1878 llvm::Constant *typeEncoding = MakeConstantString(typeStr);
1879 InstanceMethodTypes.push_back(typeEncoding);
1880 fields.add(MakeConstantString(getter->getSelector().getAsString()));
1881 fields.add(typeEncoding);
1883 fields.add(NULLPtr);
1884 fields.add(NULLPtr);
1888 llvm::Constant *typeEncoding = MakeConstantString(typeStr);
1889 InstanceMethodTypes.push_back(typeEncoding);
1890 fields.add(MakeConstantString(setter->getSelector().getAsString()));
1891 fields.add(typeEncoding);
1893 fields.add(NULLPtr);
1894 fields.add(NULLPtr);
1897 fields.finishAndAddTo(propertiesArray);
1900 reqPropertiesArray.finishAndAddTo(reqPropertiesList);
1902 reqPropertiesList.finishAndCreateGlobal(
".objc_property_list",
1903 CGM.getPointerAlign());
1905 optPropertiesArray.finishAndAddTo(optPropertiesList);
1906 OptionalPropertyList =
1907 optPropertiesList.finishAndCreateGlobal(
".objc_property_list",
1908 CGM.getPointerAlign());
1916 auto Elements = Builder.beginStruct();
1918 llvm::ConstantExpr::getIntToPtr(
1919 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1921 MakeConstantString(ProtocolName,
".objc_protocol_name"));
1922 Elements.add(ProtocolList);
1923 Elements.add(InstanceMethodList);
1924 Elements.add(ClassMethodList);
1925 Elements.add(OptionalInstanceMethodList);
1926 Elements.add(OptionalClassMethodList);
1927 Elements.add(PropertyList);
1928 Elements.add(OptionalPropertyList);
1929 ExistingProtocols[ProtocolName] =
1930 llvm::ConstantExpr::getBitCast(
1931 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.getPointerAlign()),
1934 void CGObjCGNU::GenerateProtocolHolderCategory() {
1940 auto Elements = Builder.beginStruct();
1942 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
1943 const std::string CategoryName =
"AnotherHack";
1944 Elements.add(MakeConstantString(CategoryName));
1945 Elements.add(MakeConstantString(ClassName));
1947 Elements.addBitCast(GenerateMethodList(
1948 ClassName, CategoryName, MethodSels, MethodTypes,
false), PtrTy);
1950 Elements.addBitCast(GenerateMethodList(
1951 ClassName, CategoryName, MethodSels, MethodTypes,
true), PtrTy);
1955 auto ProtocolList = ProtocolListBuilder.beginStruct();
1956 ProtocolList.add(NULLPtr);
1957 ProtocolList.addInt(LongTy, ExistingProtocols.size());
1958 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
1959 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1960 iter != endIter ; iter++) {
1961 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
1963 ProtocolElements.finishAndAddTo(ProtocolList);
1964 Elements.addBitCast(
1965 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
1966 CGM.getPointerAlign()),
1968 Categories.push_back(llvm::ConstantExpr::getBitCast(
1969 Elements.finishAndCreateGlobal(
"", CGM.getPointerAlign()),
1985 int bitCount = bits.size();
1986 int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
1987 if (bitCount < ptrBits) {
1989 for (
int i=0 ; i<bitCount ; ++i) {
1990 if (bits[i]) val |= 1ULL<<(i+1);
1992 return llvm::ConstantInt::get(IntPtrTy, val);
1996 while (v < bitCount) {
1998 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
1999 if (bits[v]) word |= 1<<i;
2002 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
2006 auto fields = builder.beginStruct();
2007 fields.addInt(Int32Ty, values.size());
2008 auto array = fields.beginArray();
2009 for (
auto v : values) array.add(v);
2010 array.finishAndAddTo(fields);
2012 llvm::Constant *GS =
2013 fields.finishAndCreateGlobal(
"", CharUnits::fromQuantity(4));
2014 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
2025 InstanceMethodSels.push_back(
I->getSelector());
2026 std::string TypeStr = CGM.getContext().getObjCEncodingForMethodDecl(
I);
2027 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2034 ClassMethodSels.push_back(
I->getSelector());
2035 std::string TypeStr = CGM.getContext().getObjCEncodingForMethodDecl(
I);
2036 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2044 E = Protos.
end();
I !=
E; ++
I)
2045 Protocols.push_back((*I)->getNameAsString());
2048 auto Elements = Builder.beginStruct();
2049 Elements.add(MakeConstantString(CategoryName));
2050 Elements.add(MakeConstantString(ClassName));
2052 Elements.addBitCast(
2053 GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,
2054 InstanceMethodTypes,
false),
2057 Elements.addBitCast(
2058 GenerateMethodList(ClassName, CategoryName, ClassMethodSels,
2059 ClassMethodTypes,
true),
2062 Elements.addBitCast(GenerateProtocolList(Protocols), PtrTy);
2063 Categories.push_back(llvm::ConstantExpr::getBitCast(
2064 Elements.finishAndCreateGlobal(
"", CGM.getPointerAlign()),
2074 llvm::StructType *propertyMetadataTy =
2075 llvm::StructType::get(CGM.getLLVMContext(),
2076 { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
2077 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2079 unsigned numProperties = 0;
2081 (void) propertyImpl;
2086 auto propertyList = builder.beginStruct();
2087 propertyList.addInt(IntTy, numProperties);
2088 propertyList.add(NULLPtr);
2089 auto properties = propertyList.beginArray(propertyMetadataTy);
2094 auto fields = properties.beginStruct(propertyMetadataTy);
2096 bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
2097 ObjCPropertyImplDecl::Synthesize);
2098 bool isDynamic = (propertyImpl->getPropertyImplementation() ==
2099 ObjCPropertyImplDecl::Dynamic);
2101 fields.add(MakePropertyEncodingString(property, OID));
2102 PushPropertyAttributes(fields, property, isSynthesized, isDynamic);
2105 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2106 if (isSynthesized) {
2107 InstanceMethodTypes.push_back(TypeEncoding);
2108 InstanceMethodSels.push_back(getter->getSelector());
2110 fields.add(MakeConstantString(getter->getSelector().getAsString()));
2111 fields.add(TypeEncoding);
2113 fields.add(NULLPtr);
2114 fields.add(NULLPtr);
2118 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2119 if (isSynthesized) {
2120 InstanceMethodTypes.push_back(TypeEncoding);
2121 InstanceMethodSels.push_back(setter->getSelector());
2123 fields.add(MakeConstantString(setter->getSelector().getAsString()));
2124 fields.add(TypeEncoding);
2126 fields.add(NULLPtr);
2127 fields.add(NULLPtr);
2129 fields.finishAndAddTo(properties);
2131 properties.finishAndAddTo(propertyList);
2133 return propertyList.finishAndCreateGlobal(
".objc_property_list",
2134 CGM.getPointerAlign());
2151 std::string SuperClassName;
2152 if (SuperClassDecl) {
2154 EmitClassRef(SuperClassName);
2164 std::string classSymbolName =
"__objc_class_name_" + ClassName;
2165 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
2166 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
2168 new llvm::GlobalVariable(TheModule, LongTy,
false,
2170 llvm::ConstantInt::get(LongTy, 0),
2184 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
2188 int superInstanceSize = !SuperClassDecl ? 0 :
2192 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2193 instanceSize = 0 - (instanceSize - superInstanceSize);
2199 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
2201 std::string TypeStr;
2203 IvarTypes.push_back(MakeConstantString(TypeStr));
2205 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
2206 uint64_t
Offset = BaseOffset;
2207 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2208 Offset = BaseOffset - superInstanceSize;
2210 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
2212 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
2213 IVD->getNameAsString();
2214 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
2216 OffsetVar->setInitializer(OffsetValue);
2222 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
2225 "__objc_ivar_offset_value_" + ClassName +
"." +
2226 IVD->getNameAsString());
2227 IvarOffsets.push_back(OffsetValue);
2228 IvarOffsetValues.add(OffsetVar);
2231 case Qualifiers::OCL_Strong:
2232 StrongIvars.push_back(
true);
2233 WeakIvars.push_back(
false);
2235 case Qualifiers::OCL_Weak:
2236 StrongIvars.push_back(
false);
2237 WeakIvars.push_back(
true);
2240 StrongIvars.push_back(
false);
2241 WeakIvars.push_back(
false);
2244 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
2245 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
2246 llvm::GlobalVariable *IvarOffsetArray =
2247 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
2248 CGM.getPointerAlign());
2254 InstanceMethodSels.push_back(
I->getSelector());
2256 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2259 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
2260 InstanceMethodTypes);
2266 ClassMethodSels.push_back(
I->getSelector());
2268 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2273 Protocols.push_back(
I->getNameAsString());
2276 llvm::Constant *SuperClass;
2277 if (!SuperClassName.empty()) {
2278 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
2280 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2285 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
2286 InstanceMethodSels, InstanceMethodTypes,
false);
2287 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
2288 ClassMethodSels, ClassMethodTypes,
true);
2289 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
2301 llvm::Type *IndexTy = Int32Ty;
2302 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
2303 llvm::ConstantInt::get(IndexTy, 1),
nullptr,
2304 llvm::ConstantInt::get(IndexTy, 2) };
2306 unsigned ivarIndex = 0;
2309 const std::string Name =
"__objc_ivar_offset_" + ClassName +
'.'
2310 + IVD->getNameAsString();
2311 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
2313 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
2314 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
2315 offsetPointerIndexes);
2317 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
2319 offset->setInitializer(offsetValue);
2326 offset =
new llvm::GlobalVariable(TheModule, offsetValue->getType(),
2332 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
2335 llvm::Constant *MetaClassStruct = GenerateClassStructure(
2336 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
2337 GenerateIvarList(empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr,
2338 NULLPtr, ZeroPtr, ZeroPtr,
true);
2339 if (CGM.getTriple().isOSBinFormatCOFF()) {
2340 auto Storage = llvm::GlobalValue::DefaultStorageClass;
2342 Storage = llvm::GlobalValue::DLLImportStorageClass;
2344 Storage = llvm::GlobalValue::DLLExportStorageClass;
2345 cast<llvm::GlobalValue>(MetaClassStruct)->setDLLStorageClass(Storage);
2349 llvm::Constant *ClassStruct = GenerateClassStructure(
2350 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
2351 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
2352 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
2353 StrongIvarBitmap, WeakIvarBitmap);
2354 if (CGM.getTriple().isOSBinFormatCOFF()) {
2355 auto Storage = llvm::GlobalValue::DefaultStorageClass;
2357 Storage = llvm::GlobalValue::DLLImportStorageClass;
2359 Storage = llvm::GlobalValue::DLLExportStorageClass;
2360 cast<llvm::GlobalValue>(ClassStruct)->setDLLStorageClass(Storage);
2364 if (ClassPtrAlias) {
2365 ClassPtrAlias->replaceAllUsesWith(
2366 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
2367 ClassPtrAlias->eraseFromParent();
2368 ClassPtrAlias =
nullptr;
2370 if (MetaClassPtrAlias) {
2371 MetaClassPtrAlias->replaceAllUsesWith(
2372 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
2373 MetaClassPtrAlias->eraseFromParent();
2374 MetaClassPtrAlias =
nullptr;
2378 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
2379 Classes.push_back(ClassStruct);
2382 llvm::Function *CGObjCGNU::ModuleInitFunction() {
2384 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
2389 GenerateProtocolHolderCategory();
2391 llvm::StructType *selStructTy =
2392 dyn_cast<llvm::StructType>(SelectorTy->getElementType());
2393 llvm::Type *selStructPtrTy = SelectorTy;
2395 selStructTy = llvm::StructType::get(CGM.getLLVMContext(),
2396 { PtrToInt8Ty, PtrToInt8Ty });
2397 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
2401 llvm::Constant *statics = NULLPtr;
2402 if (!ConstantStrings.empty()) {
2403 llvm::GlobalVariable *fileStatics = [&] {
2405 auto staticsStruct = builder.beginStruct();
2407 StringRef stringClass = CGM.getLangOpts().ObjCConstantStringClass;
2408 if (stringClass.empty()) stringClass =
"NXConstantString";
2409 staticsStruct.add(MakeConstantString(stringClass,
2410 ".objc_static_class_name"));
2412 auto array = staticsStruct.beginArray();
2413 array.addAll(ConstantStrings);
2415 array.finishAndAddTo(staticsStruct);
2417 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
2418 CGM.getPointerAlign());
2422 auto allStaticsArray = builder.beginArray(fileStatics->getType());
2423 allStaticsArray.add(fileStatics);
2424 allStaticsArray.addNullPointer(fileStatics->getType());
2426 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
2427 CGM.getPointerAlign());
2428 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
2434 unsigned selectorCount;
2437 llvm::GlobalVariable *selectorList = [&] {
2439 auto selectors = builder.beginArray(selStructTy);
2441 for (
auto &entry : table) {
2443 std::string selNameStr = entry.first.getAsString();
2444 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
2446 for (TypedSelector &sel : entry.second) {
2447 llvm::Constant *selectorTypeEncoding = NULLPtr;
2448 if (!sel.first.empty())
2449 selectorTypeEncoding =
2450 MakeConstantString(sel.first,
".objc_sel_types");
2452 auto selStruct = selectors.beginStruct(selStructTy);
2453 selStruct.add(selName);
2454 selStruct.add(selectorTypeEncoding);
2455 selStruct.finishAndAddTo(selectors);
2458 selectorAliases.push_back(sel.second);
2463 selectorCount = selectors.size();
2469 auto selStruct = selectors.beginStruct(selStructTy);
2470 selStruct.add(NULLPtr);
2471 selStruct.add(NULLPtr);
2472 selStruct.finishAndAddTo(selectors);
2474 return selectors.finishAndCreateGlobal(
".objc_selector_list",
2475 CGM.getPointerAlign());
2479 for (
unsigned i = 0; i < selectorCount; ++i) {
2480 llvm::Constant *idxs[] = {
2482 llvm::ConstantInt::get(Int32Ty, i)
2485 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
2486 selectorList->getValueType(), selectorList, idxs);
2489 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
2490 selectorAliases[i]->replaceAllUsesWith(selPtr);
2491 selectorAliases[i]->eraseFromParent();
2494 llvm::GlobalVariable *symtab = [&] {
2496 auto symtab = builder.beginStruct();
2499 symtab.addInt(LongTy, selectorCount);
2501 symtab.addBitCast(selectorList, selStructPtrTy);
2504 symtab.addInt(CGM.Int16Ty, Classes.size());
2506 symtab.addInt(CGM.Int16Ty, Categories.size());
2509 auto classList = symtab.beginArray(PtrToInt8Ty);
2510 classList.addAll(Classes);
2511 classList.addAll(Categories);
2513 classList.add(statics);
2514 classList.add(NULLPtr);
2515 classList.finishAndAddTo(symtab);
2518 return symtab.finishAndCreateGlobal(
"", CGM.getPointerAlign());
2523 llvm::Constant *module = [&] {
2524 llvm::Type *moduleEltTys[] = {
2525 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
2527 llvm::StructType *moduleTy =
2528 llvm::StructType::get(CGM.getLLVMContext(),
2529 makeArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
2532 auto module = builder.beginStruct(moduleTy);
2534 module.addInt(LongTy, RuntimeVersion);
2536 module.addInt(LongTy, CGM.getDataLayout().getTypeStoreSize(moduleTy));
2543 module.add(MakeConstantString(path,
".objc_source_file_name"));
2546 if (RuntimeVersion >= 10) {
2547 switch (CGM.getLangOpts().getGC()) {
2548 case LangOptions::GCOnly:
2549 module.addInt(IntTy, 2);
2551 case LangOptions::NonGC:
2552 if (CGM.getLangOpts().ObjCAutoRefCount)
2553 module.addInt(IntTy, 1);
2555 module.addInt(IntTy, 0);
2557 case LangOptions::HybridGC:
2558 module.addInt(IntTy, 1);
2563 return module.finishAndCreateGlobal(
"", CGM.getPointerAlign());
2569 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
2572 llvm::BasicBlock *EntryBB =
2575 Builder.SetInsertPoint(EntryBB);
2577 llvm::FunctionType *FT =
2578 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
2579 llvm::Value *Register = CGM.CreateRuntimeFunction(FT,
"__objc_exec_class");
2580 Builder.CreateCall(Register, module);
2582 if (!ClassAliases.empty()) {
2583 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
2584 llvm::FunctionType *RegisterAliasTy =
2585 llvm::FunctionType::get(Builder.getVoidTy(),
2589 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
2591 llvm::BasicBlock *AliasBB =
2593 llvm::BasicBlock *NoAliasBB =
2597 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
2598 llvm::Constant::getNullValue(RegisterAlias->getType()));
2599 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
2602 Builder.SetInsertPoint(AliasBB);
2604 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
2605 iter != ClassAliases.end(); ++iter) {
2606 llvm::Constant *TheClass =
2607 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
2609 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
2610 Builder.CreateCall(RegisterAlias,
2611 {TheClass, MakeConstantString(iter->second)});
2615 Builder.CreateBr(NoAliasBB);
2618 Builder.SetInsertPoint(NoAliasBB);
2620 Builder.CreateRetVoid();
2622 return LoadFunction;
2625 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
2629 StringRef CategoryName = OCD ? OCD->
getName() :
"";
2630 StringRef ClassName = CD->
getName();
2635 llvm::FunctionType *MethodTy =
2638 MethodName, isClassMethod);
2640 llvm::Function *Method
2648 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
2649 return GetPropertyFn;
2652 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
2653 return SetPropertyFn;
2656 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
2661 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
2662 return GetStructPropertyFn;
2665 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
2666 return SetStructPropertyFn;
2669 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
2673 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
2677 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
2678 return EnumerationMutationFn;
2683 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
2700 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
2705 bool ClearInsertionPoint) {
2710 ExceptionAsObject = Exception;
2713 "Unexpected rethrow outside @catch block.");
2717 llvm::CallSite Throw =
2719 Throw.setDoesNotReturn();
2720 CGF.
Builder.CreateUnreachable();
2721 if (ClearInsertionPoint)
2722 CGF.
Builder.ClearInsertionPoint();
2728 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
2729 return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
2736 src = EnforceType(B, src, IdTy);
2737 dst = EnforceType(B, dst, PtrToIdTy);
2738 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
2746 src = EnforceType(B, src, IdTy);
2747 dst = EnforceType(B, dst, PtrToIdTy);
2749 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
2750 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
2758 src = EnforceType(B, src, IdTy);
2759 dst = EnforceType(B, dst, IdTy);
2760 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
2767 src = EnforceType(B, src, IdTy);
2768 dst = EnforceType(B, dst, PtrToIdTy);
2769 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
2778 DestPtr = EnforceType(B, DestPtr, PtrTy);
2779 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
2781 B.CreateCall(MemMoveFn.getType(), MemMoveFn,
2785 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2788 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
2793 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2794 if (!IvarOffsetPointer) {
2798 uint64_t Offset = -1;
2805 if (!CGM.getContext().getObjCImplementation(
2806 const_cast<ObjCInterfaceDecl *>(ID)))
2807 Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2809 llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
2815 if (CGM.getLangOpts().PICLevel) {
2816 llvm::GlobalVariable *IvarOffsetGV =
new llvm::GlobalVariable(TheModule,
2818 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+
".guess");
2819 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2820 IvarOffsetGV->getType(),
false, llvm::GlobalValue::LinkOnceAnyLinkage,
2821 IvarOffsetGV,
Name);
2823 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2824 llvm::Type::getInt32PtrTy(VMContext),
false,
2828 return IvarOffsetPointer;
2835 unsigned CVRQualifiers) {
2838 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2839 EmitIvarOffset(CGF, ID, Ivar));
2861 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2867 if (RuntimeVersion < 10 ||
2869 return CGF.
Builder.CreateZExtOrBitCast(
2872 ObjCIvarOffsetVariable(Interface, Ivar),
2874 CharUnits::fromQuantity(4)),
2876 std::string name =
"__objc_ivar_offset_value_" +
2879 llvm::Value *Offset = TheModule.getGlobalVariable(name);
2881 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
2882 false, llvm::GlobalValue::LinkOnceAnyLinkage,
2883 llvm::Constant::getNullValue(IntTy), name);
2888 if (Offset->getType() != PtrDiffTy)
2889 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
2892 uint64_t Offset = ComputeIvarBaseOffset(CGF.
CGM, Interface, Ivar);
2893 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
2899 case ObjCRuntime::GNUstep:
2900 return new CGObjCGNUstep(CGM);
2902 case ObjCRuntime::GCC:
2903 return new CGObjCGCC(CGM);
2905 case ObjCRuntime::ObjFW:
2906 return new CGObjCObjFW(CGM);
2908 case ObjCRuntime::FragileMacOSX:
2909 case ObjCRuntime::MacOSX:
2910 case ObjCRuntime::iOS:
2911 case ObjCRuntime::WatchOS:
2912 llvm_unreachable(
"these runtimes are not GNU runtimes");
2914 llvm_unreachable(
"bad runtime");
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Defines the clang::ASTContext interface.
static std::string SymbolNameForMethod(StringRef ClassName, StringRef CategoryName, const Selector MethodName, bool isClassMethod)
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
static Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
External linkage, which indicates that the entity can be referred to from other translation units...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
Smart pointer class that efficiently represents Objective-C method names.
A (possibly-)qualified type.
Represents a version number in the form major[.minor[.subminor[.build]]].
Defines the clang::FileManager interface and associated types.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
The standard implementation of ConstantInitBuilder used in Clang.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
Implements runtime-specific code generation functions.
Defines the SourceManager interface.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Decl - This represents one declaration (or definition), e.g.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Represents Objective-C's @throw statement.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
ObjCMethodDecl - Represents an instance or class method declaration.
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
Defines the Objective-C statement AST node classes.
llvm::Constant * getPointer() const
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
One of these records is kept for each identifier that is lexed.
This table allows us to fully hide how we implement multi-keyword caching.
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isAnyPointerType() const
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void InitTempAlloca(Address Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca which will be observable at all locati...
ObjCContainerDecl - Represents a container for method declarations.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits getPointerSize() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
ObjCRuntime()
A bogus initialization of the runtime.
StringRef getName() const
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Represents an Objective-C protocol declaration.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
propimpl_range property_impls() const
detail::InMemoryDirectory::const_iterator I
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
CGBlockInfo - Information to generate a block literal.
const TargetInfo & getTarget() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
llvm::Value * getPointer() const
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
DeclContext * getDeclContext()
ASTContext & getContext() const
Represents Objective-C's @synchronized statement.
void add(RValue rvalue, QualType type, bool needscopy=false)
bool isObjCIdType() const
bool isInstanceMethod() const
clang::ObjCRuntime ObjCRuntime
bool isa(CodeGen::Address addr)
void add(llvm::Constant *value)
Add a new value to this initializer.
'gnustep' is the modern non-fragile GNUstep runtime.
ObjCCategoryDecl * getCategoryDecl() const
The l-value was considered opaque, so the alignment was determined from a type.
void addInt(llvm::IntegerType *intTy, uint64_t value, bool isSigned=false)
Add an integer value of a specific type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
ASTContext & getContext() const
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
CharUnits getSize() const
getSize - Get the record size in characters.
Interfaces are the core concept in Objective-C for object oriented design.
const ObjCInterfaceDecl * getClassInterface() const
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
Cached information about one file (either on disk or in the virtual file system). ...
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
const LangOptions & getLangOpts() const
std::string getAsString() const
Derive the full selector name (e.g.
Represents one property declaration in an Objective-C interface.
const VersionTuple & getVersion() const
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
All available information about a concrete callee.
FileID getMainFileID() const
Returns the FileID of the main source file.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
ObjCIvarDecl * getNextIvar()
CharUnits getAlignment() const
Return the alignment of this pointer.
instmeth_range instance_methods() const
This class organizes the cross-function state that is used while generating LLVM code.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
The basic abstraction for the target Objective-C runtime.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
StringRef getName() const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
llvm::PointerType * getType() const
Return the type of the pointer value.
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl * getSetterMethodDecl() const
instprop_range instance_properties() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
bool isObjCQualifiedIdType() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
protocol_range protocols() const
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
classmeth_range class_methods() const
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
BoundNodesTreeBuilder *const Builder
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
StringLiteral - This represents a string literal expression, e.g.
ObjCInterfaceDecl * getSuperClass() const
TranslationUnitDecl - The top declaration context.
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
LValue - This represents an lvalue references.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
TranslationUnitDecl * getTranslationUnitDecl()
CallArgList - Type for representing both the value and type of arguments in a call.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
This class handles loading and caching of source files into memory.
Abstract information about a function or function prototype.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **callOrInvoke=nullptr)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCProtocolList & getReferencedProtocols() const
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.