Patch to rewrite objc qualified types which occur in

block pointer type arguments. Partial fix for 
// rdar: //8608902

llvm-svn: 118205
This commit is contained in:
Fariborz Jahanian 2010-11-03 23:29:24 +00:00
parent bc9b31c493
commit 147e1cbb49
2 changed files with 77 additions and 7 deletions

View File

@ -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;
}

View File

@ -58,3 +58,23 @@ typedef void (^void_block_t)(void);
@end
// rdar: //8608902
@protocol CoreDAVAccountInfoProvider;
@protocol CodeProvider;
typedef void (^BDVDiscoveryCompletionHandler)(int success, id<CoreDAVAccountInfoProvider> discoveredInfo);
typedef void (^BDVDiscoveryCompletion)(id<CodeProvider> codeInfo, int success, id<CoreDAVAccountInfoProvider> discoveredInfo);
typedef void (^BDVDiscovery)(int success);
typedef void (^BDVDisc)(id<CoreDAVAccountInfoProvider> discoveredInfo, id<CodeProvider> codeInfo,
int success, id<CoreDAVAccountInfoProvider, CodeProvider> Info);
typedef void (^BLOCK)(id, id<CoreDAVAccountInfoProvider>, id<CodeProvider> codeInfo);
typedef void (^EMPTY_BLOCK)();
typedef void (^ BDVDiscoveryCompletion1 )(id<CodeProvider> codeInfo, int success, id<CoreDAVAccountInfoProvider> discoveredInfo);
void (^BL)(void(^arg1)(), int i1, void(^arg)(int));
typedef void (^iscoveryCompletionHandler)(void(^arg1)(), id<CoreDAVAccountInfoProvider> discoveredInfo);
typedef void (^DVDisc)(id<CoreDAVAccountInfoProvider> discoveredInfo, id<CodeProvider> codeInfo,
void(^arg1)(), int i1, void(^arg)(id<CoreDAVAccountInfoProvider>),
int success, id<CoreDAVAccountInfoProvider, CodeProvider> Info);