diff options
-rw-r--r-- | include/clang/Rewrite/Rewriter.h | 2 | ||||
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 12 | ||||
-rw-r--r-- | lib/Rewrite/Rewriter.cpp | 5 | ||||
-rw-r--r-- | test/Rewriter/rewrite-nested-ivar.mm | 33 |
4 files changed, 45 insertions, 7 deletions
diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h index 1692180a6d..e625b4a36e 100644 --- a/include/clang/Rewrite/Rewriter.h +++ b/include/clang/Rewrite/Rewriter.h @@ -190,7 +190,7 @@ public: /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty /// printer to generate the replacement code. This returns true if the input /// could not be rewritten, or false if successful. - bool ReplaceStmt(Stmt *From, Stmt *To); + bool ReplaceStmt(Stmt *From, Stmt *To, int Size=0); /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID. /// If no modification has been made to it, return null. diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index c56055599b..68d9b27c40 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -167,7 +167,7 @@ namespace { virtual void HandleTranslationUnit(ASTContext &C); - void ReplaceStmt(Stmt *Old, Stmt *New) { + void ReplaceStmt(Stmt *Old, Stmt *New, int Size=0) { Stmt *ReplacingStmt = ReplacedNodes[Old]; if (ReplacingStmt) @@ -177,7 +177,7 @@ namespace { return; // Used when rewriting the assignment of a property setter. // If replacement succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceStmt(Old, New)) { + if (!Rewrite.ReplaceStmt(Old, New, Size)) { ReplacedNodes[Old] = New; return; } @@ -1247,8 +1247,12 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, // delete IV; leak for now, see RewritePropertySetter() usage for more info. return ME; } - - ReplaceStmt(IV->getBase(), PE); + // Get the old text, only to get its size. + std::string SStr; + llvm::raw_string_ostream S(SStr); + IV->getBase()->printPretty(S, *Context, 0, PrintingPolicy(LangOpts)); + // Get the new text + ReplaceStmt(IV->getBase(), PE, S.str().size()); // Cannot delete IV->getBase(), since PE points to it. // Replace the old base with the cast. This is important when doing // embedded rewrites. For example, [newInv->_container addObject:0]. diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp index 9744496ac4..96a2a06a44 100644 --- a/lib/Rewrite/Rewriter.cpp +++ b/lib/Rewrite/Rewriter.cpp @@ -207,9 +207,10 @@ bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength, /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty /// printer to generate the replacement code. This returns true if the input /// could not be rewritten, or false if successful. -bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) { +bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To, int Size) { // Measaure the old text. - int Size = getRangeSize(From->getSourceRange()); + if (!Size) + Size = getRangeSize(From->getSourceRange()); if (Size == -1) return true; diff --git a/test/Rewriter/rewrite-nested-ivar.mm b/test/Rewriter/rewrite-nested-ivar.mm new file mode 100644 index 0000000000..bbc9d28d25 --- /dev/null +++ b/test/Rewriter/rewrite-nested-ivar.mm @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s +// radar 7583971 + + +@interface NSURLResponse { +@public + NSURLResponse *InnerResponse; +} +@end + +@interface NSCachedURLResponseInternal +{ + @public + NSURLResponse *response; +} +@end + +@interface NSCachedURLResponse +{ + @private + NSCachedURLResponseInternal *_internal; +} +- (void) Meth; +@end + +@implementation NSCachedURLResponse +- (void) Meth { + _internal->response->InnerResponse = 0; + } +@end + +// CHECK-LP: ((struct NSURLResponse_IMPL *)((struct NSCachedURLResponseInternal_IMPL *)((struct NSCachedURLResponse_IMPL *)self)->_internal)->response)->InnerResponse |