<html>
<head>
</head>
<body class='hmmessage'><div dir='ltr'>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style>
<div dir="ltr">Hello, trying to replace a text (spfically ":" at the beginning of an initialization list) when I run my program it causes a segmentation fault due to the marked line. The function "findSymbolAfterLocation" returns the right SourceLocation of the ":", but then it crashs. What surprises me is that it works fine in all the other cases, it finds the character I want to clear and does it. This is the source code: <br><br><blockquote>class ConstructorInitializerDelete : public MatchFinder::MatchCallback {<br>public :<br> <br> /// This function adapted from clang/lib/ARCMigrate/Transforms.cpp<br> /// If no symbol is found or the location is inside a macro, the returned<br> /// source location will be invalid.<br> SourceLocation findSymbolAfterLocation(SourceLocation loc, ASTContext* Ctx, char c) {<br> SourceManager &SM = Ctx->getSourceManager();<br> if (loc.isMacroID()) <br> if (!Lexer::isAtEndOfMacroExpansion(loc, SM,Ctx->getLangOpts(), &loc))<br> return SourceLocation();<br> loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx->getLangOpts());<br><br> // Break down the source location.<br> std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);<br><br> // Try to load the file buffer.<br> bool invalidTemp = false;<br> StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);<br> if (invalidTemp)<br> return SourceLocation();<br><br> const char *tokenBegin = file.data() + locInfo.second;<br><br> // Lex from the start of the given location.<br> Lexer lexer(SM.getLocForStartOfFile(locInfo.first),<br> Ctx->getLangOpts(),<br> file.begin(), tokenBegin, file.end());<br> Token tok;<br> lexer.LexFromRawLexer(tok);<br> switch (c){<br> case ',': if (tok.isNot(tok::comma))<br> return findSymbolAfterLocation(tok.getLocation(), Ctx, c);<br> break;<br> case ':': if (tok.isNot(tok::colon))<br> return findSymbolAfterLocation(tok.getLocation(), Ctx, c);<br> break;<br> case ';': if (tok.isNot(tok::semi))<br> return findSymbolAfterLocation(tok.getLocation(), Ctx, c);<br> break;<br> }<br> return tok.getLocation();<br> }<br> <br> virtual void run(const MatchFinder::MatchResult &Result) {<br> ASTContext *Context = Result.Context;<br> <br> const Stmt *FS1;<br> const CXXConstructorDecl *FS2;<br> <br> if ((FS1 = Result.Nodes.getNodeAs<clang::Stmt>("CID1"))<br> || (FS2 = Result.Nodes.getNodeAs<clang::CXXConstructorDecl>("CID2"))){<br> <br> FullSourceLoc FullLocation;<br> <br> if (FS1) {<br> FullLocation = Context->getFullLoc(FS1->getLocStart()); <br> }<br> else if (FS2){<br> FullLocation = Context->getFullLoc(FS2->getLocStart());<br> }<br> if (FullLocation.isValid() && !Context->getSourceManager().isInSystemHeader(FullLocation) <br> && !Context->getSourceManager().isInExternCSystemHeader(FullLocation)){<br> if (FS1){<br> FS1->dump();<br> }<br> else if (FS2){<br> FS2->dump();<br> }<br> llvm::outs() << "\nFound declaration at "<br> << FullLocation.getSpellingLineNumber() << ":"<br> << FullLocation.getSpellingColumnNumber() << "\n";<br> <br> SourceRange r;<br> SourceLocation source;<br> <br> if (FS1) {<br> r = FS1->getSourceRange();<br> char label[50];<br> sprintf(label, "//Deleted assignment operation");<br> Rewriter Rewrite;<br> Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());<br> Rewrite.ReplaceText(r,label);<br> <br> source = findSymbolAfterLocation(FS1->getLocStart(), Context, ';');<br> <br> if((source.isValid()) && (source != FS1->getLocStart())){<br> Rewrite.ReplaceText(source,1,"");<br> }<br> const RewriteBuffer *RewriteBuf = Rewrite.getRewriteBufferFor(FullLocation.getFileID());<br> llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end());<br> }<br> else if (FS2){<br> for(CXXConstructorDecl::init_const_iterator i = FS2->init_begin(); i != FS2->init_end(); i++){<br> if (((*i)->isWritten()) && ((*i)->isMemberInitializer()) && (!(*i)->getMember()->getType().isConstQualified())){ <br> char label[50]; <br> r = (*i)->getSourceRange();<br> Rewriter Rewrite2;<br> // If there is a single initializer, clears ":"<br> if ((i == FS2->init_begin()) && (i+1 == FS2->init_end())){<br> unsigned nparam = FS2->getNumParams();<br> const ParmVarDecl* parm = FS2->getParamDecl(nparam-1);<br> ----------------------------------------------------------------------------------------------<br> source = findSymbolAfterLocation(parm->getLocation(), Context, ':'); <- This line<br> ----------------------------------------------------------------------------------------------<br> llvm::outs() << "\nsource: " << source.printToString(Context->getSourceManager()) << "\n";<br> <br> if((source.isValid()) && (source != parm->getLocation())) <br> Rewrite2.ReplaceText(source,1,"");<br> }<br> <br> sprintf(label,"//Deleted initializer");<br> Rewrite2.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());<br> Rewrite2.ReplaceText(r,label);<br> <br> // If it isn't the last initializer, clears the comma that follows<br> if (i+1 < FS2->init_end()){<br> <br> source = findSymbolAfterLocation((*i)->getSourceLocation(), Context, ',');<br> <br> if((source.isValid()) && (source != (*i)->getSourceLocation()))<br> Rewrite2.ReplaceText(source,1,"");<br> }<br> <br> // If it is the last initializer and not the only, clears the comma that precedes<br> if ((i+1 == FS2->init_end()) && ((*i)->getSourceOrder() > 1)){<br> <br> source = findSymbolAfterLocation((*(i-1))->getSourceLocation(), Context, ',');<br> <br> if((source.isValid()) && (source != (*(i-1))->getSourceLocation()))<br> Rewrite2.ReplaceText(source,1,"");<br> }<br> const RewriteBuffer *RewriteBuf2 = Rewrite2.getRewriteBufferFor(FullLocation.getFileID());<br> llvm::outs() << std::string(RewriteBuf2->begin(), RewriteBuf2->end());<br> }<br> }<br> }<br> }<br> }<br> }<br>};<br><br></blockquote>Can someone help me? Thanks.<br></div>
</div></body>
</html>