summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-06-21 19:42:38 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-06-21 19:42:38 +0000
commit9b83be832bf6b2ad2143550838f126f9436049ff (patch)
treed32691c81d0cfc8e0c5798fdba019f4f0fa9b161 /clang/lib/Sema/SemaExprObjC.cpp
parentd0abdab8d18f055d8fc3b8327d7628e5f237ae7c (diff)
downloadbcm5719-llvm-9b83be832bf6b2ad2143550838f126f9436049ff.tar.gz
bcm5719-llvm-9b83be832bf6b2ad2143550838f126f9436049ff.zip
objc-arc: Add support for unbridged cast of
__builtin___CFStringMakeConstantString and CF typed function calls with explicit cf_returns_retained/cf_returns_not_retained attributes. // rdar://9544832 llvm-svn: 133535
Diffstat (limited to 'clang/lib/Sema/SemaExprObjC.cpp')
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp58
1 files changed, 39 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index ff3f837bace..83b01f24a21 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -1552,36 +1552,56 @@ namespace {
bool
Sema::ValidObjCARCNoBridgeCastExpr(Expr *&Exp, QualType castType) {
- Expr *NewExp = Exp->IgnoreParenImpCasts();
+ Expr *NewExp = Exp->IgnoreParenCasts();
- if (!isa<ObjCMessageExpr>(NewExp) && !isa<ObjCPropertyRefExpr>(NewExp))
+ if (!isa<ObjCMessageExpr>(NewExp) && !isa<ObjCPropertyRefExpr>(NewExp)
+ && !isa<CallExpr>(NewExp))
return false;
ObjCMethodDecl *method = 0;
+ bool MethodReturnsPlusOne = false;
+
if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(NewExp)) {
method = PRE->getExplicitProperty()->getGetterMethodDecl();
}
- else {
- ObjCMessageExpr *ME = cast<ObjCMessageExpr>(NewExp);
+ else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(NewExp))
method = ME->getMethodDecl();
+ else {
+ CallExpr *CE = cast<CallExpr>(NewExp);
+ Decl *CallDecl = CE->getCalleeDecl();
+ if (!CallDecl)
+ return false;
+ if (CallDecl->hasAttr<CFReturnsNotRetainedAttr>())
+ return true;
+ MethodReturnsPlusOne = CallDecl->hasAttr<CFReturnsRetainedAttr>();
+ if (!MethodReturnsPlusOne) {
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(CallDecl))
+ if (const IdentifierInfo *Id = ND->getIdentifier())
+ if (Id->isStr("__builtin___CFStringMakeConstantString"))
+ return true;
+ }
}
- if (!method)
- return false;
- if (method->hasAttr<CFReturnsNotRetainedAttr>())
- return true;
- bool MethodReturnsPlusOne = method->hasAttr<CFReturnsRetainedAttr>();
+
if (!MethodReturnsPlusOne) {
- ObjCMethodFamily family = method->getSelector().getMethodFamily();
- switch (family) {
- case OMF_alloc:
- case OMF_copy:
- case OMF_mutableCopy:
- case OMF_new:
- MethodReturnsPlusOne = true;
- break;
- default:
- break;
+ if (!method)
+ return false;
+ if (method->hasAttr<CFReturnsNotRetainedAttr>())
+ return true;
+ MethodReturnsPlusOne = method->hasAttr<CFReturnsRetainedAttr>();
+ if (!MethodReturnsPlusOne) {
+ ObjCMethodFamily family = method->getSelector().getMethodFamily();
+ switch (family) {
+ case OMF_alloc:
+ case OMF_copy:
+ case OMF_mutableCopy:
+ case OMF_new:
+ MethodReturnsPlusOne = true;
+ break;
+ default:
+ break;
+ }
}
}
+
if (MethodReturnsPlusOne) {
TypeSourceInfo *TSInfo =
Context.getTrivialTypeSourceInfo(castType, SourceLocation());
OpenPOWER on IntegriCloud