aboutsummaryrefslogtreecommitdiff
path: root/lib/Rewrite/RewriteObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-11-03 23:29:24 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-11-03 23:29:24 +0000
commite985d01390a828d9ea679c26c711d5509fd27709 (patch)
tree786dfbd57feebebe941ce110447a8b733df371bc /lib/Rewrite/RewriteObjC.cpp
parent389db16c63eec6ecfa9b235155252d8da766e94e (diff)
Patch to rewrite objc qualified types which occur in
block pointer type arguments. Partial fix for // rdar: //8608902 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118205 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Rewrite/RewriteObjC.cpp')
-rw-r--r--lib/Rewrite/RewriteObjC.cpp64
1 files changed, 57 insertions, 7 deletions
diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp
index 19fc9e239d..068636c562 100644
--- a/lib/Rewrite/RewriteObjC.cpp
+++ b/lib/Rewrite/RewriteObjC.cpp
@@ -423,6 +423,7 @@ namespace {
return false;
}
bool PointerTypeTakesAnyBlockArguments(QualType QT);
+ bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
void GetExtentOfArgList(const char *Name, const char *&LParen,
const char *&RParen);
void RewriteCastExpr(CStyleCastExpr *CE);
@@ -4888,6 +4889,26 @@ bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
return false;
}
+bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
+ const FunctionProtoType *FTP;
+ const PointerType *PT = QT->getAs<PointerType>();
+ if (PT) {
+ FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+ } else {
+ const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+ assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+ FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+ }
+ if (FTP) {
+ for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
+ E = FTP->arg_type_end(); I != E; ++I)
+ if ((*I)->isObjCQualifiedIdType() ||
+ (*I)->isObjCQualifiedInterfaceType())
+ return true;
+ }
+ return false;
+}
+
void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
const char *&RParen) {
const char *argPtr = strchr(Name, '(');
@@ -4931,28 +4952,57 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
// scan backward (from the decl location) for the end of the previous decl.
while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
startBuf--;
-
+ SourceLocation Start = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
+ std::string buf;
+ unsigned OrigLength=0;
// *startBuf != '^' if we are dealing with a pointer to function that
// may take block argument types (which will be handled below).
if (*startBuf == '^') {
// Replace the '^' with '*', computing a negative offset.
- DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
- ReplaceText(DeclLoc, 1, "*");
+ buf = '*';
+ startBuf++;
+ OrigLength++;
}
- if (PointerTypeTakesAnyBlockArguments(DeclT)) {
+ while (*startBuf != ')') {
+ buf += *startBuf;
+ startBuf++;
+ OrigLength++;
+ }
+ buf += ')';
+ OrigLength++;
+
+ if (PointerTypeTakesAnyBlockArguments(DeclT) ||
+ PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
// Replace the '^' with '*' for arguments.
+ // Replace id<P> with id/*<>*/
DeclLoc = ND->getLocation();
startBuf = SM->getCharacterData(DeclLoc);
const char *argListBegin, *argListEnd;
GetExtentOfArgList(startBuf, argListBegin, argListEnd);
while (argListBegin < argListEnd) {
- if (*argListBegin == '^') {
- SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
- ReplaceText(CaretLoc, 1, "*");
+ if (*argListBegin == '^')
+ buf += '*';
+ else if (*argListBegin == '<') {
+ buf += "/*";
+ buf += *argListBegin++;
+ OrigLength++;;
+ while (*argListBegin != '>') {
+ buf += *argListBegin++;
+ OrigLength++;
+ }
+ buf += *argListBegin;
+ buf += "*/";
}
+ else
+ buf += *argListBegin;
argListBegin++;
+ OrigLength++;
}
+ buf += ')';
+ OrigLength++;
}
+ ReplaceText(Start, OrigLength, buf);
+
return;
}