зеркало из https://github.com/microsoft/clang-1.git
objc++: sythesize a helper function to be used
for copying atomic properties of c++ objects with non-trivial copy assignment in setters/getters. Not yet used. // rdar://6137845 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147636 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
ce52bb3dec
Коммит
84e49865cb
|
@ -809,9 +809,9 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
|
|||
EmitStmt(propImpl->getSetterCXXAssignment());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
|
||||
ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
|
||||
ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
|
||||
ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
|
||||
|
||||
PropertyImplStrategy strategy(CGM, propImpl);
|
||||
|
@ -944,6 +944,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
|
|||
/// is illegal within a category.
|
||||
void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
|
||||
const ObjCPropertyImplDecl *PID) {
|
||||
GenerateObjCAtomicCopyHelperFunction(PID);
|
||||
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
|
||||
ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
|
||||
assert(OMD && "Invalid call to generate setter (empty method)");
|
||||
|
@ -2481,4 +2482,90 @@ void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
|
|||
Builder.CreateCall(extender, object)->setDoesNotThrow();
|
||||
}
|
||||
|
||||
/// GenerateObjCAtomicCopyHelperFunction - Given a c++ object type with
|
||||
/// non-trivial copy assignment function, produce following helper function.
|
||||
/// static void copyHelper(Ty *dest, const Ty *source) { *dest = *source; }
|
||||
///
|
||||
llvm::Constant *
|
||||
CodeGenFunction::GenerateObjCAtomicCopyHelperFunction(
|
||||
const ObjCPropertyImplDecl *PID) {
|
||||
if (!getLangOptions().CPlusPlus)
|
||||
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))
|
||||
return 0;
|
||||
assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null");
|
||||
|
||||
ASTContext &C = getContext();
|
||||
IdentifierInfo *II
|
||||
= &CGM.getContext().Idents.get("__copy_helper_atomic_property_");
|
||||
FunctionDecl *FD = FunctionDecl::Create(C,
|
||||
C.getTranslationUnitDecl(),
|
||||
SourceLocation(),
|
||||
SourceLocation(), II, C.VoidTy, 0,
|
||||
SC_Static,
|
||||
SC_None,
|
||||
false,
|
||||
true);
|
||||
|
||||
QualType DestTy = C.getPointerType(Ty);
|
||||
QualType SrcTy = Ty;
|
||||
SrcTy.addConst();
|
||||
SrcTy = C.getPointerType(SrcTy);
|
||||
|
||||
FunctionArgList args;
|
||||
ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
|
||||
args.push_back(&dstDecl);
|
||||
ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
|
||||
args.push_back(&srcDecl);
|
||||
|
||||
const CGFunctionInfo &FI =
|
||||
CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo());
|
||||
|
||||
llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);
|
||||
|
||||
llvm::Function *Fn =
|
||||
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
||||
"__copy_helper_atomic_property_", &CGM.getModule());
|
||||
|
||||
if (CGM.getModuleDebugInfo())
|
||||
DebugInfo = CGM.getModuleDebugInfo();
|
||||
|
||||
|
||||
StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
|
||||
|
||||
DeclRefExpr *DstExpr =
|
||||
new (C) DeclRefExpr(&dstDecl, DestTy,
|
||||
VK_RValue, SourceLocation());
|
||||
|
||||
Expr* DST = new (C) UnaryOperator(DstExpr, UO_Deref, DestTy->getPointeeType(),
|
||||
VK_LValue, OK_Ordinary, SourceLocation());
|
||||
|
||||
DeclRefExpr *SrcExpr =
|
||||
new (C) DeclRefExpr(&srcDecl, SrcTy,
|
||||
VK_RValue, SourceLocation());
|
||||
|
||||
Expr* SRC = new (C) UnaryOperator(SrcExpr, UO_Deref, SrcTy->getPointeeType(),
|
||||
VK_LValue, OK_Ordinary, SourceLocation());
|
||||
|
||||
Expr *Args[2] = { DST, SRC };
|
||||
CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
|
||||
CXXOperatorCallExpr *TheCall =
|
||||
new (C) CXXOperatorCallExpr(C, OO_Equal, CalleeExp->getCallee(),
|
||||
Args, 2, DestTy->getPointeeType(),
|
||||
VK_LValue, SourceLocation());
|
||||
|
||||
EmitStmt(TheCall);
|
||||
|
||||
FinishFunction();
|
||||
|
||||
return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
|
||||
|
||||
}
|
||||
|
||||
|
||||
CGObjCRuntime::~CGObjCRuntime() {}
|
||||
|
|
|
@ -1333,6 +1333,8 @@ public:
|
|||
|
||||
llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);
|
||||
llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo);
|
||||
llvm::Constant *GenerateObjCAtomicCopyHelperFunction(
|
||||
const ObjCPropertyImplDecl *PID);
|
||||
|
||||
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче