void ApplyArgumentsCallback::run( const ast_matchers::MatchFinder::MatchResult& result) { const CallExpr* callExpr = result.Nodes.getDeclAs<CallExpr>("toCall"); if (callExpr) { if (callExpr->getNumArgs() > 0) { const Expr* lastArgExpr = callExpr->getArg(callExpr->getNumArgs() - 1); std::string lastArg = getText(*result.SourceManager, *lastArgExpr); _replacements.insert(Replacement(*result.SourceManager, lastArgExpr, lastArg + ", " + _arguments)); } else { // look for the next token: a '(' clang::SourceLocation insertLoc = clang::Lexer::findLocationAfterToken(callExpr->getLocStart(), clang::tok::l_paren, *result.SourceManager, clang::LangOptions(), /*skip Whitespace? */ true); _replacements.insert(Replacement(*result.SourceManager, insertLoc, 0, _arguments)); } } }
TEST_F(ReplacementTest, CanApplyReplacements) { FileID ID = Context.createInMemoryFile("input.cpp", "line1\nline2\nline3\nline4"); Replacements Replaces; Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 5, "replaced")); Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 3, 1), 5, "other")); EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_EQ("line1\nreplaced\nother\nline4", Context.getRewrittenText(ID)); }
TEST(ShiftedCodePositionTest, FindsNewCodePosition) { Replacements Replaces; Replaces.insert(Replacement("", 0, 1, "")); Replaces.insert(Replacement("", 4, 3, " ")); // Assume ' int i;' is turned into 'int i;' and cursor is located at '|'. EXPECT_EQ(0u, shiftedCodePosition(Replaces, 0)); // |int i; EXPECT_EQ(0u, shiftedCodePosition(Replaces, 1)); // |nt i; EXPECT_EQ(1u, shiftedCodePosition(Replaces, 2)); // i|t i; EXPECT_EQ(2u, shiftedCodePosition(Replaces, 3)); // in| i; EXPECT_EQ(3u, shiftedCodePosition(Replaces, 4)); // int| i; EXPECT_EQ(4u, shiftedCodePosition(Replaces, 5)); // int | i; EXPECT_EQ(4u, shiftedCodePosition(Replaces, 6)); // int |i; EXPECT_EQ(4u, shiftedCodePosition(Replaces, 7)); // int |; EXPECT_EQ(5u, shiftedCodePosition(Replaces, 8)); // int i| }
TEST(ShiftedCodePositionTest, FindsNewCodePositionWithInserts) { Replacements Replaces; Replaces.insert(Replacement("", 4, 0, "\"\n\"")); // Assume '"12345678"' is turned into '"1234"\n"5678"'. EXPECT_EQ(4u, shiftedCodePosition(Replaces, 4)); // "123|5678" EXPECT_EQ(8u, shiftedCodePosition(Replaces, 5)); // "1234|678" }
TEST_F(ReplacementTest, ApplyAllFailsIfOneApplyFails) { // This test depends on the value of the file name of an invalid source // location being in the range ]a, z[. FileID IDa = Context.createInMemoryFile("a.cpp", "text"); FileID IDz = Context.createInMemoryFile("z.cpp", "text"); Replacements Replaces; Replaces.insert(Replacement(Context.Sources, Context.getLocation(IDa, 1, 1), 4, "a")); Replaces.insert(Replacement(Context.Sources, SourceLocation(), 5, "2")); Replaces.insert(Replacement(Context.Sources, Context.getLocation(IDz, 1, 1), 4, "z")); EXPECT_FALSE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_EQ("a", Context.getRewrittenText(IDa)); EXPECT_EQ("z", Context.getRewrittenText(IDz)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto decl = result.Nodes.getNodeAs<CXXMethodDecl>("returnQListIterator"); if (decl==nullptr) { return; } auto str = getText(*result.SourceManager,*decl); std::string in = str; std::regex re("QListIterator\\s*<\\s*(\\w+)\\s*>\\s*\\((.*)\\)"); std::smatch m; std::string out; while (std::regex_search(in, m, re)) { out += m.prefix(); std::regex re("QListIterator\\s*<\\s*(\\w+)\\s*>\\s*\\(\\*(.*)\\)"); out += std::regex_replace(m[0].str(), re, "std::list<$1*>::iterator ($2->begin())"); in = m.suffix(); } out += in; in = out; re = "QListIterator\\s*<\\s*(\\w+)\\s*>"; out = ""; while (std::regex_search(in, m, re)) { out += m.prefix(); std::regex re("QListIterator\\s*<\\s*(\\w+)\\s*>"); out += std::regex_replace(m[0].str(), re, "std::list<$1*>::iterator"); in = m.suffix(); } out += in; Replace->insert(Replacement(*result.SourceManager, decl, out)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto call = result.Nodes.getNodeAs<CXXMemberCallExpr>("setAutoDeleteTRUE"); if (call==nullptr) { return; } Replace->insert(Replacement(*result.SourceManager, call, "")); const auto thisDecl = result.Nodes.getNodeAs<VarDecl>("thisDecl"); if (thisDecl==nullptr) { return; } auto callStr = getText(*result.SourceManager,*call); auto thisDeclStr = getText(*result.SourceManager,*thisDecl); // place to use shared_ptr if (! findNreplace(thisDeclStr,"QList<(\\w+)>","std::list<$1*>") ) return; Replace->insert(Replacement(*result.SourceManager, thisDecl, thisDeclStr)); }
void ReplacedImages::replace(const Color & from, const Color & to) { if (index >= MAX_COLOR_REPLACE) { std::cout << "Max color replacements reached" << std::endl; return; } colors[index++] = Replacement(from, to); }
void ReplacedImages::replace(Color from, Color to) { if (index >= MAX_COLOR_REPLACE) { std::cout << "Max color replacements reached" << std::endl; return; } from.disable(); colors[index++] = Replacement(from, to); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto cxxNewExpr = result.Nodes.getNodeAs<CXXNewExpr>("qlist::cxxNewExpr"); if (cxxNewExpr==nullptr) { return; } auto str = getText(*result.SourceManager,*cxxNewExpr); if (! findNreplace(str,"QList<(\\w+)>","std::list<$1*>") ) return; Replace->insert(Replacement(*result.SourceManager, cxxNewExpr, str)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto fdecl = result.Nodes.getNodeAs<FunctionDecl>("returnQList"); if (fdecl==nullptr) { return; } auto str = getText(*result.SourceManager,*fdecl); if (! findNreplace(str,"QList<(\\w+)>","std::list<$1*>") ) return; Replace->insert(Replacement(*result.SourceManager, fdecl, str)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto decl = result.Nodes.getNodeAs<ParmVarDecl>("parmVarDecl"); if (decl==nullptr) { llvm::errs() <<"Unable to get decl\n"; return; } auto str = getText(*result.SourceManager,*decl); if (! findNreplace(str,"QList<(\\w+)>","std::list<$1*>") ) return; Replace->insert(Replacement(*result.SourceManager, decl, str)); }
void ReplacedImages::set_transparent(TransparentColor value) { if (index >= MAX_COLOR_REPLACE) { std::cout << "Max color replacements reached" << std::endl; return; } Color c = Color(value); c.enable(); colors[index++] = Replacement(c, Color(0, 0, 0, 0)); }
TEST_F(FlushRewrittenFilesTest, StoresChangesOnDisk) { FileID ID = createFile("input.cpp", "line1\nline2\nline3\nline4"); Replacements Replaces; Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 5, "replaced")); EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_FALSE(Context.Rewrite.overwriteChangedFiles()); EXPECT_EQ("line1\nreplaced\nline3\nline4", getFileContentFromDisk("input.cpp")); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto fdecl = result.Nodes.getNodeAs<CXXConstructExpr>("qlistIterator"); if (fdecl==nullptr) { return; } auto str = getText(*result.SourceManager,*fdecl); if (! findNreplace(str, "QListIterator<(\\w+)>\\((\\w+)\\)", "std::list<$1*>::iterator(@B$2.@Ebegin())") ) if (! findNreplace(str,"(\\w+)ListIterator (\\w+)\\((.*)\\)","std::list<$1*>::iterator $2(@B$3.@Ebegin())") ) return; Replace->insert(Replacement(*result.SourceManager, fdecl, str)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { std::string m="count"; const auto call = result.Nodes.getNodeAs<CXXMemberCallExpr>(m); if (call==nullptr) { llvm::errs() << "unable to get " << m << "\n"; return; } const auto callee = call->getCallee(); auto str = getText(*result.SourceManager,*callee); if (! findNreplace(str,m,"size") ) return; Replace->insert(Replacement(*result.SourceManager, callee, str)); }
void FixKernelParameterCallback::rewriteParameter( const clang::ParmVarDecl* param, const std::string& dataType, const std::string& paramName, SourceManager& sM) { std::ostringstream oss; oss << "__global " << dataType << "* "; oss << paramName << "_data"; oss << ", unsigned int " << paramName << "_col_count"; _replacements.insert(Replacement(sM, param, oss.str())); }
void RenameTypedefCallback::run( const ast_matchers::MatchFinder::MatchResult& result) { const TypedefNameDecl* typedefDecl = result.Nodes.getDeclAs<TypedefNameDecl>("decl"); if (typedefDecl && typedefDecl->getName() == _oldName) { _replacements.insert(Replacement(*result.SourceManager, typedefDecl, "typedef " + typedefDecl->getUnderlyingType().getAsString() + " " + _newName)); } }
void RedefineTypedefCallback::run( const ast_matchers::MatchFinder::MatchResult& result) { const TypedefNameDecl* typedefDecl = result.Nodes.getDeclAs<TypedefNameDecl>("decl"); if (typedefDecl && typedefDecl->getName() == _typedefName) { _replacements.insert(Replacement(*result.SourceManager, typedefDecl, "typedef " + _newType + " " + _typedefName)); } }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto varDecl = result.Nodes.getNodeAs<Stmt>("thisDeclPrepend"); if (varDecl == nullptr) { return; } const auto call = result.Nodes.getNodeAs<CXXMemberCallExpr>("prepend"); if (call==nullptr) { return; } auto str = getText(*result.SourceManager,*call); if (! findNreplace(str,"prepend\\((.*)\\)","push_front($1)") ) return; Replace->insert(Replacement(*result.SourceManager, call, str)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { auto decl = result.Nodes.getNodeAs<CXXRecordDecl>("inheritsQListIterator"); if (decl==nullptr) { return; } if (!decl->hasDefinition()) return; // this is needed so bases_begin doesn't crash auto it = decl->bases_begin(); for (; it && it != decl->bases_end(); ++it) { auto str = getText(*result.SourceManager,it->getLocStart(),it->getLocEnd()) ; if (! findNreplace(str,"QListIterator<(\\w+)>","std::list<$1*>::iterator") ) return; Replace->insert(Replacement(*result.SourceManager, it, str)); } }
void FixKernelParameterCallback::adoptBody(const FunctionDecl* funcDecl, const std::string& fullType, const std::string& paramName, SourceManager& sM) { std::ostringstream oss; oss << fullType << " " << paramName << ";\n"; oss << paramName << ".data = " << paramName << "_data;\n"; oss << paramName << ".col_count = " << paramName << "_col_count;\n"; auto body = dyn_cast<CompoundStmt>(funcDecl->getBody()); _replacements.insert( Replacement(sM, (*(body->body_begin()))->getLocStart(), 0, oss.str())); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto fdecl = result.Nodes.getNodeAs<ForStmt>("forStmtIterator"); if (fdecl==nullptr) { return; } auto str = getText(*result.SourceManager,*fdecl); // for (ali.toFirst();!hasDocs && (a=ali.current());++ali) // for (ali.toFirst();!hasDocs && (ali!=this->end() && a=*ali);++ali) //----- // for (ali.toFirst();!hasDocs && (a=ali.current());++ali) // for (;(a=ali.current());++ali) if (! findNreplace(str, "\\(.*\\.toFirst\\(\\);(.*)\\((\\w+)=(\\w+).current\\(\\)\\);", "(; $1 (@X$2,$3@Y); ") ) if (! findNreplace(str, "\\((\\w+)=(\\w+).current\\(\\)\\)", "(@X$1,$2@Y)") ) return; Replace->insert(Replacement(*result.SourceManager, fdecl, str)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto decl = result.Nodes.getNodeAs<VarDecl>("varDeclIterator"); if (decl==nullptr) { llvm::errs() <<"Unable to get decl\n"; return; } auto str = getText(*result.SourceManager,*decl); if (! findNreplace(str,"QListIterator\\s*<\\s*(\\w+)\\s*>\\s*(\\w+)\\(\\*(.*)\\)","std::list<$1*>::iterator $2(@B$3->@Ebegin())") ) if (! findNreplace(str,"QListIterator\\s*<\\s*(\\w+)\\s*>\\s*(\\w+)\\((.*)\\)","std::list<$1*>::iterator $2(@B$3.@Ebegin())") ) if (! findNreplace(str,"QListIterator\\s*<\\s*(\\w+)\\s*>\\s*\\((.*)\\)","std::list<$1*>::iterator ($2->begin())") ) if (! findNreplace(str,"QListIterator\\s*<\\s*(\\w+)\\s*>","std::list<$1*>::iterator") ) if (! findNreplace(str,"(\\w+)ListIterator (\\w+)\\(\\*(.*)\\)","std::list<$1*>::iterator $2(@B$3->@Ebegin())") ) if (! findNreplace(str,"(\\w+)ListIterator (\\w+)\\((.*)\\)","std::list<$1*>::iterator $2(@B$3.@Ebegin())") ) if (! findNreplace(str,"(\\w+)ListIterator","std::list<$1*>::iterator") ) return; Replace->insert(Replacement(*result.SourceManager, decl, str)); }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { const auto call = result.Nodes.getNodeAs<CXXConstructorDecl>("Field_setAutoDeleteTRUE"); if (call==nullptr) { return; } const auto fdecl = result.Nodes.getNodeAs<FieldDecl>("C"); if (fdecl==nullptr) { return; } auto callStr = getText(*result.SourceManager,*call); if (callStr.find("setAutoDelete(TRUE)") == std::string::npos) { return; } if (g_unique_fdecl.find(fdecl) != g_unique_fdecl.end()) { return; } auto fdeclStr = getText(*result.SourceManager,*fdecl); // place to use shared_ptr if (! findNreplace(fdeclStr,"QList<(\\w+)>","std::list<$1*>") ) return; Replace->insert(Replacement(*result.SourceManager, fdecl, fdeclStr)); g_unique_fdecl.insert(fdecl); }
Replacement createReplacement(SourceLocation Start, unsigned Length, llvm::StringRef ReplacementText) { return Replacement(Context.Sources, Start, Length, ReplacementText); }
bool VisitCallExpr(CallExpr *Call) { if (Call->getDirectCallee()->getName() == "F") { Replace = Replacement(*SM, Call, ""); } return true; }
bool VisitCXXRecordDecl(CXXRecordDecl *Record) { if (Record->getName() == "X") { Replace = Replacement(*SM, Record, ""); } return true; }
static inline Replacement getEmptyKey() { return Replacement(0,0); }
static inline Replacement getTombstoneKey() { return Replacement(0, (Value*)-1); }