[cfe-commits] r46622 - in /cfe/trunk: Driver/RewriteTest.cpp Rewrite/Rewriter.cpp include/clang/Rewrite/Rewriter.h

Chris Lattner sabre at nondot.org
Thu Jan 31 11:51:04 PST 2008


Author: lattner
Date: Thu Jan 31 13:51:04 2008
New Revision: 46622

URL: http://llvm.org/viewvc/llvm-project?rev=46622&view=rev
Log:
add some helper methods for removing and replacing text, this makes the
rewriter more robust.

Modified:
    cfe/trunk/Driver/RewriteTest.cpp
    cfe/trunk/Rewrite/Rewriter.cpp
    cfe/trunk/include/clang/Rewrite/Rewriter.h

Modified: cfe/trunk/Driver/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteTest.cpp?rev=46622&r1=46621&r2=46622&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Thu Jan 31 13:51:04 2008
@@ -102,7 +102,7 @@
     }
     
     void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen) {
-      // If replacement succeeded or warning disabled return with no warning.
+      // If insertion succeeded or warning disabled return with no warning.
       if (!Rewrite.InsertText(Loc, StrData, StrLen) ||
           SilenceRewriteMacroWarning)
         return;
@@ -110,7 +110,24 @@
       Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
     }
     
+    void RemoveText(SourceLocation Loc, unsigned StrLen) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.RemoveText(Loc, StrLen) || SilenceRewriteMacroWarning)
+        return;
+      
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
 
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     const char *NewStr, unsigned NewLength) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, NewStr, NewLength) ||
+          SilenceRewriteMacroWarning)
+        return;
+      
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+    
     // Syntactic Rewriting.
     void RewritePrologue(SourceLocation Loc);
     void RewriteInclude();
@@ -410,7 +427,7 @@
         // replace import with include
         SourceLocation ImportLoc = 
           LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
-        Rewrite.ReplaceText(ImportLoc, ImportLen, "include", IncludeLen);
+        ReplaceText(ImportLoc, ImportLen, "include", IncludeLen);
         BufPtr += ImportLen;
       }
     }
@@ -443,7 +460,7 @@
       SourceLocation::getFileLoc(MainFileID, BufPtr-MainBufStart);
     
     // Rewrite the single tab character into a sequence of spaces.
-    Rewrite.ReplaceText(TabLoc, 1, "        ", Spaces);
+    ReplaceText(TabLoc, 1, "        ", Spaces);
   }
 }
 
@@ -478,8 +495,8 @@
   }
   
   // Replace the @class with typedefs corresponding to the classes.
-  Rewrite.ReplaceText(startLoc, semiPtr-startBuf+1, 
-                      typedefString.c_str(), typedefString.size());
+  ReplaceText(startLoc, semiPtr-startBuf+1, 
+              typedefString.c_str(), typedefString.size());
 }
 
 void RewriteTest::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
@@ -488,7 +505,7 @@
     
   if (SM->getLineNumber(LocEnd) > SM->getLineNumber(LocStart)) {
     InsertText(LocStart, "/* ", 3);
-    Rewrite.ReplaceText(LocEnd, 1, ";*/ ", 4);
+    ReplaceText(LocEnd, 1, ";*/ ", 4);
   } else {
     InsertText(LocStart, "// ", 3);
   }
@@ -500,7 +517,7 @@
     ObjCPropertyDecl *Property = Properties[i];
     SourceLocation Loc = Property->getLocation();
     
-    Rewrite.ReplaceText(Loc, 0, "// ", 3);
+    ReplaceText(Loc, 0, "// ", 3);
     
     // FIXME: handle properties that are declared across multiple lines.
   }
@@ -510,7 +527,7 @@
   SourceLocation LocStart = CatDecl->getLocStart();
   
   // FIXME: handle category headers that are declared across multiple lines.
-  Rewrite.ReplaceText(LocStart, 0, "// ", 3);
+  ReplaceText(LocStart, 0, "// ", 3);
   
   for (ObjCCategoryDecl::instmeth_iterator I = CatDecl->instmeth_begin(), 
        E = CatDecl->instmeth_end(); I != E; ++I)
@@ -520,7 +537,7 @@
     RewriteMethodDeclaration(*I);
 
   // Lastly, comment out the @end.
-  Rewrite.ReplaceText(CatDecl->getAtEndLoc(), 0, "// ", 3);
+  ReplaceText(CatDecl->getAtEndLoc(), 0, "// ", 3);
 }
 
 void RewriteTest::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
@@ -529,7 +546,7 @@
   SourceLocation LocStart = PDecl->getLocStart();
   
   // FIXME: handle protocol headers that are declared across multiple lines.
-  Rewrite.ReplaceText(LocStart, 0, "// ", 3);
+  ReplaceText(LocStart, 0, "// ", 3);
   
   for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(), 
        E = PDecl->instmeth_end(); I != E; ++I)
@@ -540,7 +557,7 @@
 
   // Lastly, comment out the @end.
   SourceLocation LocEnd = PDecl->getAtEndLoc();
-  Rewrite.ReplaceText(LocEnd, 0, "// ", 3);
+  ReplaceText(LocEnd, 0, "// ", 3);
 
   // Must comment out @optional/@required
   const char *startBuf = SM->getCharacterData(LocStart);
@@ -549,15 +566,15 @@
     if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
       std::string CommentedOptional = "/* @optional */";
       SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
-      Rewrite.ReplaceText(OptionalLoc, strlen("@optional"),
-                          CommentedOptional.c_str(), CommentedOptional.size());
+      ReplaceText(OptionalLoc, strlen("@optional"),
+                  CommentedOptional.c_str(), CommentedOptional.size());
       
     }
     else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
       std::string CommentedRequired = "/* @required */";
       SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
-      Rewrite.ReplaceText(OptionalLoc, strlen("@required"),
-                          CommentedRequired.c_str(), CommentedRequired.size());
+      ReplaceText(OptionalLoc, strlen("@required"),
+                  CommentedRequired.c_str(), CommentedRequired.size());
       
     }
   }
@@ -568,7 +585,7 @@
   if (LocStart.isInvalid())
     assert(false && "Invalid SourceLocation");
   // FIXME: handle forward protocol that are declared across multiple lines.
-  Rewrite.ReplaceText(LocStart, 0, "// ", 3);
+  ReplaceText(LocStart, 0, "// ", 3);
 }
 
 void RewriteTest::RewriteObjCMethodDecl(ObjCMethodDecl *OMD, 
@@ -667,8 +684,8 @@
     
     const char *startBuf = SM->getCharacterData(LocStart);
     const char *endBuf = SM->getCharacterData(LocEnd);
-    Rewrite.ReplaceText(LocStart, endBuf-startBuf,
-                        ResultStr.c_str(), ResultStr.size());
+    ReplaceText(LocStart, endBuf-startBuf,
+                ResultStr.c_str(), ResultStr.size());
   }
   
   for (ObjCCategoryImplDecl::classmeth_iterator
@@ -682,8 +699,8 @@
     
     const char *startBuf = SM->getCharacterData(LocStart);
     const char *endBuf = SM->getCharacterData(LocEnd);
-    Rewrite.ReplaceText(LocStart, endBuf-startBuf,
-                        ResultStr.c_str(), ResultStr.size());    
+    ReplaceText(LocStart, endBuf-startBuf,
+                ResultStr.c_str(), ResultStr.size());    
   }
   if (IMD)
     InsertText(IMD->getLocEnd(), "// ", 3);
@@ -722,7 +739,7 @@
     RewriteMethodDeclaration(*I);
 
   // Lastly, comment out the @end.
-  Rewrite.ReplaceText(ClassDecl->getAtEndLoc(), 0, "// ", 3);
+  ReplaceText(ClassDecl->getAtEndLoc(), 0, "// ", 3);
 }
 
 Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
@@ -899,7 +916,7 @@
   SourceLocation startLoc = S->getLocStart();
   buf = "goto __break_label_";
   buf += utostr(ObjCBcLabelNo.back());
-  Rewrite.ReplaceText(startLoc, strlen("break"), buf.c_str(), buf.size());
+  ReplaceText(startLoc, strlen("break"), buf.c_str(), buf.size());
 
   return 0;
 }
@@ -916,7 +933,7 @@
   SourceLocation startLoc = S->getLocStart();
   buf = "goto __continue_label_";
   buf += utostr(ObjCBcLabelNo.back());
-  Rewrite.ReplaceText(startLoc, strlen("continue"), buf.c_str(), buf.size());
+  ReplaceText(startLoc, strlen("continue"), buf.c_str(), buf.size());
   
   return 0;
 }
@@ -1004,8 +1021,8 @@
   startCollectionBuf += 3;
   
   // Replace: "for (type element in" with string constructed thus far. 
-  Rewrite.ReplaceText(startLoc, startCollectionBuf - startBuf,
-                      buf.c_str(), buf.size());
+  ReplaceText(startLoc, startCollectionBuf - startBuf,
+              buf.c_str(), buf.size());
   // Replace ')' in for '(' type elem in collection ')' with ';'
   SourceLocation rightParenLoc = S->getRParenLoc();
   const char *rparenBuf = SM->getCharacterData(rightParenLoc);
@@ -1046,7 +1063,7 @@
   buf += elementTypeAsString;
   buf += ")enumState.itemsPtr[counter++];";
   // Replace ')' in for '(' type elem in collection ')' with all of these.
-  Rewrite.ReplaceText(lparenLoc, 1, buf.c_str(), buf.size());
+  ReplaceText(lparenLoc, 1, buf.c_str(), buf.size());
   
   ///            __continue_label: ;
   ///        } while (counter < limit);
@@ -1101,7 +1118,7 @@
   
   std::string buf; 
   buf = "objc_sync_enter";
-  Rewrite.ReplaceText(startLoc, 13, buf.c_str(), buf.size());
+  ReplaceText(startLoc, 13, buf.c_str(), buf.size());
   SourceLocation endLoc = S->getSynchExpr()->getLocEnd();
   const char *endBuf = SM->getCharacterData(endLoc);
   endBuf++;
@@ -1115,7 +1132,7 @@
   buf += "id volatile _rethrow = 0;\n";
   buf += "objc_exception_try_enter(&_stack);\n";
   buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
-  Rewrite.ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
+  ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
   startLoc = S->getSynchBody()->getLocEnd();
   startBuf = SM->getCharacterData(startLoc);
   
@@ -1130,7 +1147,7 @@
   buf += "}\n";
   buf += "}";
   
-  Rewrite.ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+  ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
   return 0;
 }
 
@@ -1150,7 +1167,7 @@
   buf += "objc_exception_try_enter(&_stack);\n";
   buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
 
-  Rewrite.ReplaceText(startLoc, 4, buf.c_str(), buf.size());
+  ReplaceText(startLoc, 4, buf.c_str(), buf.size());
   
   startLoc = S->getTryBody()->getLocEnd();
   startBuf = SM->getCharacterData(startLoc);
@@ -1190,8 +1207,7 @@
       QualType t = dyn_cast<ValueDecl>(declStmt->getDecl())->getType();
       if (t == Context->getObjCIdType()) {
         buf += "1) { ";
-        Rewrite.ReplaceText(startLoc, lParenLoc-startBuf+1, 
-                            buf.c_str(), buf.size());
+        ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
         sawIdTypedCatch = true;
       } else if (const PointerType *pType = t->getAsPointerType()) { 
         ObjCInterfaceType *cls; // Should be a pointer to a class.
@@ -1201,8 +1217,7 @@
           buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
           buf += cls->getDecl()->getName();
           buf += "\"), (struct objc_object *)_caught)) { ";
-          Rewrite.ReplaceText(startLoc, lParenLoc-startBuf+1, 
-                              buf.c_str(), buf.size());
+          ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
         }
       }
       // Now rewrite the body...
@@ -1217,8 +1232,7 @@
       buf = " = _caught;";
       // Here we replace ") {" with "= _caught;" (which initializes and 
       // declares the @catch parameter).
-      Rewrite.ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, 
-                          buf.c_str(), buf.size());
+      ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size());
     } else if (!isa<NullStmt>(catchStmt)) {
       assert(false && "@catch rewrite bug");
     }
@@ -1243,7 +1257,7 @@
     assert((*startBuf == '@') && "bogus @finally start");
     
     buf = "/* @finally */";
-    Rewrite.ReplaceText(startLoc, 8, buf.c_str(), buf.size());
+    ReplaceText(startLoc, 8, buf.c_str(), buf.size());
     
     Stmt *body = finalStmt->getFinallyBody();
     SourceLocation startLoc = body->getLocStart();
@@ -1294,12 +1308,12 @@
     buf = "objc_exception_throw(";
   else // add an implicit argument
     buf = "objc_exception_throw(_caught";
-  Rewrite.ReplaceText(startLoc, 6, buf.c_str(), buf.size());
+  ReplaceText(startLoc, 6, buf.c_str(), buf.size());
   const char *semiBuf = strchr(startBuf, ';');
   assert((*semiBuf == ';') && "@throw: can't find ';'");
   SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
   buf = ");";
-  Rewrite.ReplaceText(semiLoc, 1, buf.c_str(), buf.size());
+  ReplaceText(semiLoc, 1, buf.c_str(), buf.size());
   return 0;
 }
 
@@ -2077,8 +2091,7 @@
   // have no ivars (thus not synthesized) then no need to synthesize this class.
   if (NumIvars <= 0 && (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
     endBuf += Lexer::MeasureTokenLength(LocEnd, *SM);
-    Rewrite.ReplaceText(LocStart, endBuf-startBuf, 
-                        Result.c_str(), Result.size());
+    ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
     return;
   }
   
@@ -2093,8 +2106,7 @@
            && "SynthesizeObjCInternalStruct - malformed @interface");
     
     // rewrite the original header *without* disturbing the '{'
-    Rewrite.ReplaceText(LocStart, cursor-startBuf-1, 
-                        Result.c_str(), Result.size());
+    ReplaceText(LocStart, cursor-startBuf-1, Result.c_str(), Result.size());
     if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
       Result = "\n    struct ";
       Result += RCDecl->getName();
@@ -2152,8 +2164,7 @@
     // -fms-extensions. If the struct definition were "inlined", we wouldn't
     // need to use this switch. That said, I don't want to inline the def.
     Result += ";\n};\n";
-    Rewrite.ReplaceText(LocStart, endBuf-startBuf, 
-                        Result.c_str(), Result.size());
+    ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
   }
   // Mark this struct as having been generated.
   if (!ObjCSynthesizedStructs.insert(CDecl))

Modified: cfe/trunk/Rewrite/Rewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Rewrite/Rewriter.cpp?rev=46622&r1=46621&r2=46622&view=diff

==============================================================================
--- cfe/trunk/Rewrite/Rewriter.cpp (original)
+++ cfe/trunk/Rewrite/Rewriter.cpp Thu Jan 31 13:51:04 2008
@@ -204,8 +204,7 @@
 }
 
 /// InsertText - Insert the specified string at the specified location in the
-/// original buffer.  This method is only valid on rewritable source
-/// locations.
+/// original buffer.
 bool Rewriter::InsertText(SourceLocation Loc,
                           const char *StrData, unsigned StrLen) {
   if (!isRewritable(Loc)) return true;
@@ -215,26 +214,27 @@
   return false;
 }
 
-/// RemoveText - Remove the specified text region.  This method is only valid
-/// on a rewritable source location.
-void Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
-  assert(isRewritable(Start) && "Not a rewritable location!");
+/// RemoveText - Remove the specified text region.
+bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
+  if (!isRewritable(Start)) return true;
   unsigned FileID;
   unsigned StartOffs = getLocationOffsetAndFileID(Start, FileID);
   getEditBuffer(FileID).RemoveText(StartOffs, Length);
+  return false;
 }
 
 /// ReplaceText - This method replaces a range of characters in the input
 /// buffer with a new string.  This is effectively a combined "remove/insert"
 /// operation.
-void Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
+bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
                            const char *NewStr, unsigned NewLength) {
-  assert(isRewritable(Start) && "Not a rewritable location!");
+  if (!isRewritable(Start)) return true;
   unsigned StartFileID;
   unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
   
   getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength,
                                          NewStr, NewLength);
+  return false;
 }
 
 /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty

Modified: cfe/trunk/include/clang/Rewrite/Rewriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/Rewriter.h?rev=46622&r1=46621&r2=46622&view=diff

==============================================================================
--- cfe/trunk/include/clang/Rewrite/Rewriter.h (original)
+++ cfe/trunk/include/clang/Rewrite/Rewriter.h Thu Jan 31 13:51:04 2008
@@ -131,14 +131,13 @@
   /// location was not rewritable, false otherwise.
   bool InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen);
   
-  /// RemoveText - Remove the specified text region.  This method is only valid
-  /// on a rewritable source location.
-  void RemoveText(SourceLocation Start, unsigned Length);
+  /// RemoveText - Remove the specified text region.
+  bool RemoveText(SourceLocation Start, unsigned Length);
   
   /// ReplaceText - This method replaces a range of characters in the input
   /// buffer with a new string.  This is effectively a combined "remove/insert"
   /// operation.
-  void ReplaceText(SourceLocation Start, unsigned OrigLength,
+  bool ReplaceText(SourceLocation Start, unsigned OrigLength,
                    const char *NewStr, unsigned NewLength);
   
   /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty





More information about the cfe-commits mailing list