[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