diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-11-03 23:29:24 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-11-03 23:29:24 +0000 |
commit | e985d01390a828d9ea679c26c711d5509fd27709 (patch) | |
tree | 786dfbd57feebebe941ce110447a8b733df371bc /lib/Rewrite/RewriteObjC.cpp | |
parent | 389db16c63eec6ecfa9b235155252d8da766e94e (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.cpp | 64 |
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; } |