diff options
Diffstat (limited to 'lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 275 |
1 files changed, 194 insertions, 81 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 68d234d..fbf8a1a 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -15,26 +15,24 @@ //===----------------------------------------------------------------------===// #include "CGObjCRuntime.h" -#include "CodeGenModule.h" -#include "CodeGenFunction.h" #include "CGCleanup.h" +#include "CodeGenFunction.h" +#include "CodeGenModule.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtObjC.h" -#include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" - -#include "llvm/Intrinsics.h" -#include "llvm/Module.h" -#include "llvm/LLVMContext.h" +#include "clang/Basic/SourceManager.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/Compiler.h" -#include "llvm/DataLayout.h" - #include <cstdarg> @@ -194,7 +192,7 @@ protected: /// The element types must match the types of the structure elements in the /// first argument. llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty, - llvm::ArrayRef<llvm::Constant*> V, + ArrayRef<llvm::Constant *> V, StringRef Name="", llvm::GlobalValue::LinkageTypes linkage =llvm::GlobalValue::InternalLinkage) { @@ -206,7 +204,7 @@ protected: /// elements that the array type declares, of the type specified as the array /// element type. llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty, - llvm::ArrayRef<llvm::Constant*> V, + ArrayRef<llvm::Constant *> V, StringRef Name="", llvm::GlobalValue::LinkageTypes linkage =llvm::GlobalValue::InternalLinkage) { @@ -217,7 +215,7 @@ protected: /// Generates a global array, inferring the array type from the specified /// element type and the size of the initialiser. llvm::GlobalVariable *MakeGlobalArray(llvm::Type *Ty, - llvm::ArrayRef<llvm::Constant*> V, + ArrayRef<llvm::Constant *> V, StringRef Name="", llvm::GlobalValue::LinkageTypes linkage =llvm::GlobalValue::InternalLinkage) { @@ -227,7 +225,7 @@ protected: /// Returns a property name and encoding string. llvm::Constant *MakePropertyEncodingString(const ObjCPropertyDecl *PD, const Decl *Container) { - ObjCRuntime R = CGM.getLangOpts().ObjCRuntime; + const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime; if ((R.getKind() == ObjCRuntime::GNUstep) && (R.getVersion() >= VersionTuple(1, 6))) { std::string NameAndAttributes; @@ -238,15 +236,44 @@ protected: NameAndAttributes += TypeStr; NameAndAttributes += '\0'; NameAndAttributes += PD->getNameAsString(); + NameAndAttributes += '\0'; return llvm::ConstantExpr::getGetElementPtr( CGM.GetAddrOfConstantString(NameAndAttributes), Zeros); } return MakeConstantString(PD->getNameAsString()); } + /// Push the property attributes into two structure fields. + void PushPropertyAttributes(std::vector<llvm::Constant*> &Fields, + ObjCPropertyDecl *property, bool isSynthesized=true, bool + isDynamic=true) { + int attrs = property->getPropertyAttributes(); + // For read-only properties, clear the copy and retain flags + if (attrs & ObjCPropertyDecl::OBJC_PR_readonly) { + attrs &= ~ObjCPropertyDecl::OBJC_PR_copy; + attrs &= ~ObjCPropertyDecl::OBJC_PR_retain; + attrs &= ~ObjCPropertyDecl::OBJC_PR_weak; + attrs &= ~ObjCPropertyDecl::OBJC_PR_strong; + } + // The first flags field has the same attribute values as clang uses internally + Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff)); + attrs >>= 8; + attrs <<= 2; + // For protocol properties, synthesized and dynamic have no meaning, so we + // reuse these flags to indicate that this is a protocol property (both set + // has no meaning, as a property can't be both synthesized and dynamic) + attrs |= isSynthesized ? (1<<0) : 0; + attrs |= isDynamic ? (1<<1) : 0; + // The second field is the next four fields left shifted by two, with the + // low bit set to indicate whether the field is synthesized or dynamic. + Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff)); + // Two padding fields + Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0)); + Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0)); + } /// Ensures that the value has the required type, by inserting a bitcast if /// required. This function lets us avoid inserting bitcasts that are /// redundant. - llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, llvm::Type *Ty){ + llvm::Value* EnforceType(CGBuilderTy &B, llvm::Value *V, llvm::Type *Ty) { if (V->getType() == Ty) return V; return B.CreateBitCast(V, Ty); } @@ -385,7 +412,7 @@ private: /// a class defined in the runtime, declaring no methods, but adopting the /// protocols. This is a horribly ugly hack, but it allows us to collect all /// of the protocols without changing the ABI. - void GenerateProtocolHolderCategory(void); + void GenerateProtocolHolderCategory(); /// Generates a class structure. llvm::Constant *GenerateClassStructure( llvm::Constant *MetaClass, @@ -409,7 +436,7 @@ private: ArrayRef<llvm::Constant *> MethodTypes); /// Returns a selector with the specified type encoding. An empty string is /// used to return an untyped selector (with the types field set to NULL). - llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, + llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel, const std::string &TypeEncoding, bool lval); /// Returns the variable used to store the offset of an instance variable. llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, @@ -419,7 +446,7 @@ private: protected: void EmitClassRef(const std::string &className); /// Emits a pointer to the named class - virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder, + virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF, const std::string &Name, bool isWeak); /// Looks up the method for sending a message to the specified object. This /// mechanism differs between the GCC and GNU runtimes, so this method must be @@ -472,11 +499,11 @@ public: bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method); - virtual llvm::Value *GetClass(CGBuilderTy &Builder, + virtual llvm::Value *GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID); - virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, + virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel, bool lval = false); - virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl + virtual llvm::Value *GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl *Method); virtual llvm::Constant *GetEHType(QualType T); @@ -485,7 +512,7 @@ public: virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD); - virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, + virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *PD); virtual void GenerateProtocol(const ObjCProtocolDecl *PD); virtual llvm::Function *ModuleInitFunction(); @@ -494,8 +521,9 @@ public: virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, bool copy); virtual llvm::Constant *GetSetStructFunction(); - virtual llvm::Constant *GetCppAtomicObjectFunction(); virtual llvm::Constant *GetGetStructFunction(); + virtual llvm::Constant *GetCppAtomicObjectGetFunction(); + virtual llvm::Constant *GetCppAtomicObjectSetFunction(); virtual llvm::Constant *EnumerationMutationFunction(); virtual void EmitTryStmt(CodeGenFunction &CGF, @@ -503,7 +531,8 @@ public: virtual void EmitSynchronizedStmt(CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S); virtual void EmitThrowStmt(CodeGenFunction &CGF, - const ObjCAtThrowStmt &S); + const ObjCAtThrowStmt &S, + bool ClearInsertionPoint=true); virtual llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF, llvm::Value *AddrWeakObj); virtual void EmitObjCWeakAssign(CodeGenFunction &CGF, @@ -528,7 +557,7 @@ public: virtual llvm::Value *EmitIvarOffset(CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); - virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); + virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF); virtual llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM, const CGBlockInfo &blockInfo) { return NULLPtr; @@ -537,6 +566,12 @@ public: const CGBlockInfo &blockInfo) { return NULLPtr; } + + virtual llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, + QualType T) { + return NULLPtr; + } + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { return 0; } @@ -566,7 +601,7 @@ protected: llvm::Value *args[] = { EnforceType(Builder, Receiver, IdTy), EnforceType(Builder, cmd, SelectorTy) }; - llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args); + llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); imp->setMetadata(msgSendMDKind, node); return imp.getInstruction(); } @@ -576,7 +611,7 @@ protected: CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy), cmd}; - return Builder.CreateCall(MsgLookupSuperFn, lookupArgs); + return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); } public: CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) { @@ -597,6 +632,20 @@ class CGObjCGNUstep : public CGObjCGNU { /// arguments. Returns the slot for the corresponding method. Superclass /// message lookup rarely changes, so this is a good caching opportunity. LazyRuntimeFunction SlotLookupSuperFn; + /// Specialised function for setting atomic retain properties + LazyRuntimeFunction SetPropertyAtomic; + /// Specialised function for setting atomic copy properties + LazyRuntimeFunction SetPropertyAtomicCopy; + /// Specialised function for setting nonatomic retain properties + LazyRuntimeFunction SetPropertyNonAtomic; + /// Specialised function for setting nonatomic copy properties + LazyRuntimeFunction SetPropertyNonAtomicCopy; + /// Function to perform atomic copies of C++ objects with nontrivial copy + /// constructors from Objective-C ivars. + LazyRuntimeFunction CxxAtomicObjectGetFn; + /// Function to perform atomic copies of C++ objects with nontrivial copy + /// constructors to Objective-C ivars. + LazyRuntimeFunction CxxAtomicObjectSetFn; /// Type of an slot structure pointer. This is returned by the various /// lookup functions. llvm::Type *SlotTy; @@ -629,7 +678,7 @@ class CGObjCGNUstep : public CGObjCGNU { EnforceType(Builder, ReceiverPtr, PtrToIdTy), EnforceType(Builder, cmd, SelectorTy), EnforceType(Builder, self, IdTy) }; - llvm::CallSite slot = CGF.EmitCallOrInvoke(LookupFn, args); + llvm::CallSite slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); slot.setOnlyReadsMemory(); slot->setMetadata(msgSendMDKind, node); @@ -648,13 +697,16 @@ class CGObjCGNUstep : public CGObjCGNU { CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; - llvm::CallInst *slot = Builder.CreateCall(SlotLookupSuperFn, lookupArgs); + llvm::CallInst *slot = + CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs); slot->setOnlyReadsMemory(); return Builder.CreateLoad(Builder.CreateStructGEP(slot, 4)); } public: CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNU(Mod, 9, 3) { + const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime; + llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy, NULL); SlotTy = llvm::PointerType::getUnqual(SlotStructTy); @@ -672,8 +724,69 @@ class CGObjCGNUstep : public CGObjCGNU { // void __cxa_end_catch(void) ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, NULL); // void _Unwind_Resume_or_Rethrow(void*) - ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy, PtrTy, NULL); + ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy, + PtrTy, NULL); + } else if (R.getVersion() >= VersionTuple(1, 7)) { + llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); + // id objc_begin_catch(void *e) + EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy, NULL); + // void objc_end_catch(void) + ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy, NULL); + // void _Unwind_Resume_or_Rethrow(void*) + ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy, + PtrTy, NULL); } + llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); + SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy, + SelectorTy, IdTy, PtrDiffTy, NULL); + SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy, + IdTy, SelectorTy, IdTy, PtrDiffTy, NULL); + SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy, + IdTy, SelectorTy, IdTy, PtrDiffTy, NULL); + SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy", + VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy, NULL); + // void objc_setCppObjectAtomic(void *dest, const void *src, void + // *helper); + CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy, + PtrTy, PtrTy, NULL); + // void objc_getCppObjectAtomic(void *dest, const void *src, void + // *helper); + CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy, + PtrTy, PtrTy, NULL); + } + virtual llvm::Constant *GetCppAtomicObjectGetFunction() { + // The optimised functions were added in version 1.7 of the GNUstep + // runtime. + assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= + VersionTuple(1, 7)); + return CxxAtomicObjectGetFn; + } + virtual llvm::Constant *GetCppAtomicObjectSetFunction() { + // The optimised functions were added in version 1.7 of the GNUstep + // runtime. + assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= + VersionTuple(1, 7)); + return CxxAtomicObjectSetFn; + } + virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, + bool copy) { + // The optimised property functions omit the GC check, and so are not + // safe to use in GC mode. The standard functions are fast in GC mode, + // so there is less advantage in using them. + assert ((CGM.getLangOpts().getGC() == LangOptions::NonGC)); + // The optimised functions were added in version 1.7 of the GNUstep + // runtime. + assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= + VersionTuple(1, 7)); + + if (atomic) { + if (copy) return SetPropertyAtomicCopy; + return SetPropertyAtomic; + } + if (copy) return SetPropertyNonAtomicCopy; + return SetPropertyNonAtomic; + + return 0; } }; @@ -697,7 +810,7 @@ protected: llvm::Value *args[] = { EnforceType(Builder, Receiver, IdTy), EnforceType(Builder, cmd, SelectorTy) }; - llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args); + llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); imp->setMetadata(msgSendMDKind, node); return imp.getInstruction(); } @@ -708,13 +821,13 @@ protected: CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy), cmd}; - return Builder.CreateCall(MsgLookupSuperFn, lookupArgs); + return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); } - virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder, + virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF, const std::string &Name, bool isWeak) { if (isWeak) - return CGObjCGNU::GetClassNamed(Builder, Name, isWeak); + return CGObjCGNU::GetClassNamed(CGF, Name, isWeak); EmitClassRef(Name); @@ -894,7 +1007,7 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion, } } -llvm::Value *CGObjCGNU::GetClassNamed(CGBuilderTy &Builder, +llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF, const std::string &Name, bool isWeak) { llvm::Value *ClassName = CGM.GetAddrOfConstantCString(Name); @@ -907,25 +1020,25 @@ llvm::Value *CGObjCGNU::GetClassNamed(CGBuilderTy &Builder, // with memoized versions or with static references if it's safe to do so. if (!isWeak) EmitClassRef(Name); - ClassName = Builder.CreateStructGEP(ClassName, 0); + ClassName = CGF.Builder.CreateStructGEP(ClassName, 0); llvm::Constant *ClassLookupFn = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), "objc_lookup_class"); - return Builder.CreateCall(ClassLookupFn, ClassName); + return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName); } // This has to perform the lookup every time, since posing and related // techniques can modify the name -> class mapping. -llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder, +llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID) { - return GetClassNamed(Builder, OID->getNameAsString(), OID->isWeakImported()); + return GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported()); } -llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) { - return GetClassNamed(Builder, "NSAutoreleasePool", false); +llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { + return GetClassNamed(CGF, "NSAutoreleasePool", false); } -llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel, +llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel, const std::string &TypeEncoding, bool lval) { SmallVector<TypedSelector, 2> &Types = SelectorTable[Sel]; @@ -948,23 +1061,23 @@ llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel, } if (lval) { - llvm::Value *tmp = Builder.CreateAlloca(SelValue->getType()); - Builder.CreateStore(SelValue, tmp); + llvm::Value *tmp = CGF.CreateTempAlloca(SelValue->getType()); + CGF.Builder.CreateStore(SelValue, tmp); return tmp; } return SelValue; } -llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel, +llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel, bool lval) { - return GetSelector(Builder, Sel, std::string(), lval); + return GetSelector(CGF, Sel, std::string(), lval); } -llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl - *Method) { +llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, + const ObjCMethodDecl *Method) { std::string SelTypes; CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes); - return GetSelector(Builder, Method->getSelector(), SelTypes, false); + return GetSelector(CGF, Method->getSelector(), SelTypes, false); } llvm::Constant *CGObjCGNU::GetEHType(QualType T) { @@ -1114,7 +1227,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, } } - llvm::Value *cmd = GetSelector(Builder, Sel); + llvm::Value *cmd = GetSelector(CGF, Sel); CallArgList ActualArgs; @@ -1249,9 +1362,9 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); llvm::Value *cmd; if (Method) - cmd = GetSelector(Builder, Method); + cmd = GetSelector(CGF, Method); else - cmd = GetSelector(Builder, Sel); + cmd = GetSelector(CGF, Sel); cmd = EnforceType(Builder, cmd, SelectorTy); Receiver = EnforceType(Builder, Receiver, IdTy); @@ -1594,12 +1707,12 @@ llvm::Constant *CGObjCGNU::GenerateProtocolList(ArrayRef<std::string>Protocols){ return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list"); } -llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder, +llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *PD) { llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()]; llvm::Type *T = CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); - return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); + return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); } llvm::Constant *CGObjCGNU::GenerateEmptyProtocol( @@ -1703,8 +1816,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { // simplify the runtime library by allowing it to use the same data // structures for protocol metadata everywhere. llvm::StructType *PropertyMetadataTy = llvm::StructType::get( - PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, - PtrToInt8Ty, NULL); + PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, + PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, NULL); std::vector<llvm::Constant*> Properties; std::vector<llvm::Constant*> OptionalProperties; @@ -1716,12 +1829,9 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { std::vector<llvm::Constant*> Fields; ObjCPropertyDecl *property = *iter; + Fields.push_back(MakePropertyEncodingString(property, 0)); + PushPropertyAttributes(Fields, property); - Fields.push_back(MakePropertyEncodingString(property, PD)); - - Fields.push_back(llvm::ConstantInt::get(Int8Ty, - property->getPropertyAttributes())); - Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0)); if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { std::string TypeStr; Context.getObjCEncodingForMethodDecl(getter,TypeStr); @@ -1804,7 +1914,7 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements, ".objc_protocol"), IdTy); } -void CGObjCGNU::GenerateProtocolHolderCategory(void) { +void CGObjCGNU::GenerateProtocolHolderCategory() { // Collect information about instance methods SmallVector<Selector, 1> MethodSels; SmallVector<llvm::Constant*, 1> MethodTypes; @@ -1872,7 +1982,7 @@ llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) { } return llvm::ConstantInt::get(IntPtrTy, val); } - llvm::SmallVector<llvm::Constant*, 8> values; + SmallVector<llvm::Constant *, 8> values; int v=0; while (v < bitCount) { int32_t word = 0; @@ -1951,15 +2061,13 @@ llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OI SmallVectorImpl<Selector> &InstanceMethodSels, SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) { ASTContext &Context = CGM.getContext(); - // - // Property metadata: name, attributes, isSynthesized, setter name, setter - // types, getter name, getter types. + // Property metadata: name, attributes, attributes2, padding1, padding2, + // setter name, setter types, getter name, getter types. llvm::StructType *PropertyMetadataTy = llvm::StructType::get( - PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, - PtrToInt8Ty, NULL); + PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, + PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, NULL); std::vector<llvm::Constant*> Properties; - // Add all of the property methods need adding to the method list and to the // property metadata list. for (ObjCImplDecl::propimpl_iterator @@ -1970,11 +2078,11 @@ llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OI ObjCPropertyImplDecl *propertyImpl = *iter; bool isSynthesized = (propertyImpl->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize); + bool isDynamic = (propertyImpl->getPropertyImplementation() == + ObjCPropertyImplDecl::Dynamic); Fields.push_back(MakePropertyEncodingString(property, OID)); - Fields.push_back(llvm::ConstantInt::get(Int8Ty, - property->getPropertyAttributes())); - Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized)); + PushPropertyAttributes(Fields, property, isSynthesized, isDynamic); if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { std::string TypeStr; Context.getObjCEncodingForMethodDecl(getter,TypeStr); @@ -2531,7 +2639,10 @@ llvm::Constant *CGObjCGNU::GetGetStructFunction() { llvm::Constant *CGObjCGNU::GetSetStructFunction() { return SetStructPropertyFn; } -llvm::Constant *CGObjCGNU::GetCppAtomicObjectFunction() { +llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() { + return 0; +} +llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() { return 0; } @@ -2563,7 +2674,8 @@ void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF, } void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, - const ObjCAtThrowStmt &S) { + const ObjCAtThrowStmt &S, + bool ClearInsertionPoint) { llvm::Value *ExceptionAsObject; if (const Expr *ThrowExpr = S.getThrowExpr()) { @@ -2576,22 +2688,23 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, } ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy); llvm::CallSite Throw = - CGF.EmitCallOrInvoke(ExceptionThrowFn, ExceptionAsObject); + CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject); Throw.setDoesNotReturn(); CGF.Builder.CreateUnreachable(); - CGF.Builder.ClearInsertionPoint(); + if (ClearInsertionPoint) + CGF.Builder.ClearInsertionPoint(); } llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF, llvm::Value *AddrWeakObj) { - CGBuilderTy B = CGF.Builder; + CGBuilderTy &B = CGF.Builder; AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy); return B.CreateCall(WeakReadFn, AddrWeakObj); } void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dst) { - CGBuilderTy B = CGF.Builder; + CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, PtrToIdTy); B.CreateCall2(WeakAssignFn, src, dst); @@ -2600,7 +2713,7 @@ void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dst, bool threadlocal) { - CGBuilderTy B = CGF.Builder; + CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, PtrToIdTy); if (!threadlocal) @@ -2613,7 +2726,7 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dst, llvm::Value *ivarOffset) { - CGBuilderTy B = CGF.Builder; + CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, IdTy); B.CreateCall3(IvarAssignFn, src, dst, ivarOffset); @@ -2621,7 +2734,7 @@ void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dst) { - CGBuilderTy B = CGF.Builder; + CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, PtrToIdTy); B.CreateCall2(StrongCastAssignFn, src, dst); @@ -2631,7 +2744,7 @@ void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, llvm::Value *DestPtr, llvm::Value *SrcPtr, llvm::Value *Size) { - CGBuilderTy B = CGF.Builder; + CGBuilderTy &B = CGF.Builder; DestPtr = EnforceType(B, DestPtr, PtrTy); SrcPtr = EnforceType(B, SrcPtr, PtrTy); |