diff options
author | Steve Naroff <snaroff@apple.com> | 2007-11-01 13:24:47 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-11-01 13:24:47 +0000 |
commit | d5255f55ebe8803ee10b01589a64156e5e9cde5e (patch) | |
tree | dbb5fc70f0e75d31dece1b33b0954ad99a5c25ae /Driver/RewriteTest.cpp | |
parent | 770951b5bb6028a8d326ddb4a13cef7d4a128162 (diff) |
Implement rewrite rule for commenting out protocol references. For example:
extern id /*<NSObject>*/ NSAllocateObject(Class aClass, unsigned extraBytes, NSZone *zone);
extern void NSDeallocateObject(id /*<NSObject>*/object);
extern id /*<NSObject>*/ NSCopyObject(id /*<NSObject>*/object, unsigned extraBytes, NSZone *zone);
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43612 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/RewriteTest.cpp')
-rw-r--r-- | Driver/RewriteTest.cpp | 92 |
1 files changed, 68 insertions, 24 deletions
diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 026c5d62c4..e2516c850e 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -65,8 +65,9 @@ namespace { void RewriteProtocolDecl(ObjcProtocolDecl *Dcl); void RewriteMethods(int nMethods, ObjcMethodDecl **Methods); void RewriteFunctionDecl(FunctionDecl *FD); - bool functionReferencesAnyObjcQualifiedInterfaceTypes( - const FunctionTypeProto *proto); + void RewriteObjcQualifiedInterfaceTypes( + const FunctionTypeProto *proto, FunctionDecl *FD); + bool needToScanForQualifiers(QualType T); // Expression Rewriting. Stmt *RewriteFunctionBody(Stmt *S); @@ -422,31 +423,76 @@ CallExpr *RewriteTest::SynthesizeCallToFunctionDecl( return new CallExpr(ICE, args, nargs, FT->getResultType(), SourceLocation()); } -bool RewriteTest::functionReferencesAnyObjcQualifiedInterfaceTypes( - const FunctionTypeProto *proto) { - QualType resultType = proto->getResultType(); - - if (resultType == Context->getObjcIdType()) { - // FIXME: we don't currently represent "id <Protocol>" in the type system. - // Implement a heuristic here (until we do). - } else if (const PointerType *pType = resultType->getAsPointerType()) { +static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, + const char *&startRef, const char *&endRef) { + while (startBuf < endBuf) { + if (*startBuf == '<') + startRef = startBuf; // mark the start. + if (*startBuf == '>') { + assert((startRef && *startRef == '<') && "rewrite scanning error"); + endRef = startBuf; // mark the end. + return true; + } + startBuf++; + } + return false; +} + +bool RewriteTest::needToScanForQualifiers(QualType T) { + // FIXME: we don't currently represent "id <Protocol>" in the type system. + if (T == Context->getObjcIdType()) + return true; + + if (const PointerType *pType = T->getAsPointerType()) { Type *pointeeType = pType->getPointeeType().getTypePtr(); if (isa<ObjcQualifiedInterfaceType>(pointeeType)) return true; // we have "Class <Protocol> *". } + return false; +} + +void RewriteTest::RewriteObjcQualifiedInterfaceTypes( + const FunctionTypeProto *proto, FunctionDecl *FD) { + + if (needToScanForQualifiers(proto->getResultType())) { + // Since types are unique, we need to scan the buffer. + SourceLocation Loc = FD->getLocation(); + + const char *endBuf = SM->getCharacterData(Loc); + const char *startBuf = endBuf; + while (*startBuf != ';') + startBuf--; // scan backward (from the decl location) for return type. + const char *startRef = 0, *endRef = 0; + if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { + // Get the locations of the startRef, endRef. + SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf); + SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1); + // Comment out the protocol references. + Rewrite.ReplaceText(LessLoc, 0, "/*", 2); + Rewrite.ReplaceText(GreaterLoc, 0, "*/", 2); + } + } // Now check arguments. for (unsigned i = 0; i < proto->getNumArgs(); i++) { - QualType argType = proto->getArgType(i); - if (argType == Context->getObjcIdType()) { - // FIXME: we don't currently represent "id <Protocol>" in the type system. - // Implement a heuristic here (until we do). - } else if (const PointerType *pType = argType->getAsPointerType()) { - Type *pointeeType = pType->getPointeeType().getTypePtr(); - if (isa<ObjcQualifiedInterfaceType>(pointeeType)) - return true; - } + if (needToScanForQualifiers(proto->getArgType(i))) { + // Since types are unique, we need to scan the buffer. + SourceLocation Loc = FD->getLocation(); + + const char *startBuf = SM->getCharacterData(Loc); + const char *endBuf = startBuf; + while (*endBuf != ';') + endBuf++; // scan forward (from the decl location) for argument types. + const char *startRef = 0, *endRef = 0; + if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { + // Get the locations of the startRef, endRef. + SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf); + SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1); + // Comment out the protocol references. + Rewrite.ReplaceText(LessLoc, 0, "/*", 2); + Rewrite.ReplaceText(GreaterLoc, 0, "*/", 2); + } + } } - return false; } void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) { @@ -459,10 +505,8 @@ void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) { // information (id<p>, C<p>*). The protocol references need to be rewritten! const FunctionType *funcType = FD->getType()->getAsFunctionType(); assert(funcType && "missing function type"); - const FunctionTypeProto *proto = dyn_cast<FunctionTypeProto>(funcType); - if (proto && functionReferencesAnyObjcQualifiedInterfaceTypes(proto)) { - // FIXME: Rewrite function decl... - } + if (const FunctionTypeProto *proto = dyn_cast<FunctionTypeProto>(funcType)) + RewriteObjcQualifiedInterfaceTypes(proto, FD); } // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); |