aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCGNU.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp275
1 files changed, 194 insertions, 81 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 68d234dde6ea..fbf8a1abb013 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);