[cfe-commits] r147691 - in /cfe/trunk: lib/CodeGen/CGObjC.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.h test/CodeGenObjCXX/property-reference.mm
Fariborz Jahanian
fjahanian at apple.com
Fri Jan 6 14:33:54 PST 2012
Author: fjahanian
Date: Fri Jan 6 16:33:54 2012
New Revision: 147691
URL: http://llvm.org/viewvc/llvm-project?rev=147691&view=rev
Log:
objc++: more code gen stuff for atomic property api,
currently turned off. // rdar://6137845
Also, fixes a test case which should be nonatomic under
new API.
Modified:
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/test/CodeGenObjCXX/property-reference.mm
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Fri Jan 6 16:33:54 2012
@@ -776,6 +776,44 @@
copyStructFn, ReturnValueSlot(), args);
}
+/// emitCPPObjectAtomicSetterCall - Call the runtime function to store
+/// the value from the first formal parameter into the given ivar, using
+/// the Cpp API for atomic Cpp objects with non-trivial copy assignment.
+static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
+ ObjCMethodDecl *OMD,
+ ObjCIvarDecl *ivar,
+ llvm::Constant *AtomicHelperFn) {
+ // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg,
+ // AtomicHelperFn);
+ CallArgList args;
+
+ // The first argument is the address of the ivar.
+ llvm::Value *ivarAddr =
+ CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
+ CGF.LoadObjCSelf(), ivar, 0).getAddress();
+ ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
+ args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
+
+ // The second argument is the address of the parameter variable.
+ ParmVarDecl *argVar = *OMD->param_begin();
+ DeclRefExpr argRef(argVar, argVar->getType().getNonReferenceType(),
+ VK_LValue, SourceLocation());
+ llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
+ argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
+ args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
+
+ // Third argument is the helper function.
+ args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
+
+ llvm::Value *copyCppAtomicObjectFn =
+ CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
+ CGF.EmitCall(CGF.getTypes().getFunctionInfo(CGF.getContext().VoidTy, args,
+ FunctionType::ExtInfo()),
+ copyCppAtomicObjectFn, ReturnValueSlot(), args);
+
+
+}
+
static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) {
Expr *setter = PID->getSetterCXXAssignment();
if (!setter) return true;
@@ -802,17 +840,24 @@
void
CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
- const ObjCPropertyImplDecl *propImpl) {
+ const ObjCPropertyImplDecl *propImpl,
+ llvm::Constant *AtomicHelperFn) {
+ const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
+ ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
+ ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
+
// Just use the setter expression if Sema gave us one and it's
- // non-trivial. There's no way to do this atomically.
+ // non-trivial.
if (!hasTrivialSetExpr(propImpl)) {
- EmitStmt(propImpl->getSetterCXXAssignment());
+ if (!AtomicHelperFn)
+ // If non-atomic, assignment is called directly.
+ EmitStmt(propImpl->getSetterCXXAssignment());
+ else
+ // If atomic, assignment is called via a locking api.
+ emitCPPObjectAtomicSetterCall(*this, setterMethod, ivar,
+ AtomicHelperFn);
return;
}
-
- const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
- ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
- ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
PropertyImplStrategy strategy(CGM, propImpl);
switch (strategy.getKind()) {
@@ -944,13 +989,13 @@
/// is illegal within a category.
void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID) {
- GenerateObjCAtomicCopyHelperFunction(PID);
+ llvm::Constant *AtomicHelperFn = GenerateObjCAtomicCopyHelperFunction(PID);
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
assert(OMD && "Invalid call to generate setter (empty method)");
StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
- generateObjCSetterBody(IMP, PID);
+ generateObjCSetterBody(IMP, PID, AtomicHelperFn);
FinishFunction();
}
@@ -2489,15 +2534,21 @@
llvm::Constant *
CodeGenFunction::GenerateObjCAtomicCopyHelperFunction(
const ObjCPropertyImplDecl *PID) {
- if (!getLangOptions().CPlusPlus)
+ // FIXME. This api is for NeXt runtime only for now.
+ if (!getLangOptions().CPlusPlus || !getLangOptions().NeXTRuntime)
return 0;
QualType Ty = PID->getPropertyIvarDecl()->getType();
if (!Ty->isRecordType())
return 0;
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
if (!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic) ||
- hasTrivialSetExpr(PID))
+ hasTrivialSetExpr(PID) || /* temporary */ true)
return 0;
+
+ llvm::Constant * HelperFn = CGM.getAtomicHelperFnMap(Ty);
+ if (HelperFn)
+ return HelperFn;
+
assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null");
ASTContext &C = getContext();
@@ -2562,8 +2613,9 @@
EmitStmt(TheCall);
FinishFunction();
-
- return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
+ HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
+ CGM.setAtomicHelperFnMap(Ty, HelperFn);
+ return HelperFn;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Jan 6 16:33:54 2012
@@ -1310,7 +1310,8 @@
void GenerateObjCSetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID);
void generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
- const ObjCPropertyImplDecl *propImpl);
+ const ObjCPropertyImplDecl *propImpl,
+ llvm::Constant *AtomicHelperFn);
bool IndirectObjCSetterArg(const CGFunctionInfo &FI);
bool IvarTypeWithAggrGCObjects(QualType Ty);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Jan 6 16:33:54 2012
@@ -276,6 +276,8 @@
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
+
+ llvm::DenseMap<QualType, llvm::Constant *> AtomicHelperFnMap;
/// CXXGlobalInits - Global variables with initializers that need to run
/// before main.
@@ -398,6 +400,14 @@
StaticLocalDeclMap[D] = GV;
}
+ llvm::Constant *getAtomicHelperFnMap(QualType Ty) {
+ return AtomicHelperFnMap[Ty];
+ }
+ void setAtomicHelperFnMap(QualType Ty,
+ llvm::Constant *Fn) {
+ AtomicHelperFnMap[Ty] = Fn;
+ }
+
CGDebugInfo *getModuleDebugInfo() { return DebugInfo; }
ASTContext &getContext() const { return Context; }
Modified: cfe/trunk/test/CodeGenObjCXX/property-reference.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-reference.mm?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/property-reference.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/property-reference.mm Fri Jan 6 16:33:54 2012
@@ -35,7 +35,7 @@
@interface Test1 {
test1::A ivar;
}
- at property const test1::A &prop1;
+ at property (nonatomic) const test1::A &prop1;
@end
@implementation Test1
@synthesize prop1 = ivar;
More information about the cfe-commits
mailing list