So if that last email was at all ambitious; yes I am planning to write follow up patches. I actually really want to write a USR AST marcher - imagine the possibilities for editors! <br><br>On Tuesday, August 5, 2014, Matthew Plant <<a href="mailto:mplant@google.com">mplant@google.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I have no intention of ignoring reviews. I should mention that I am only at google for another week. I am happy to continue the review from my maplant2@illinois email afterwards, but there are some things that I simply cannot change within a week. Remaking the visitors AST matches for one is just something I can't do in a week, but could potentially do afterwards. I'm sorry Manuel it you got the wrong impression, I have no intention to stop the review.<div>
<br></div><div>But if you were to stop the review, I imagine it would be the death of clang rename.<br><br>On Tuesday, August 5, 2014, Chandler Carruth <<a href="javascript:_e(%7B%7D,'cvml','chandlerc@google.com');" target="_blank">chandlerc@google.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Sorry if I've gotten the wrong impression here, but reading this review it seemed like the review comments weren't really being taken seriously...</div>
<div><br></div><div>The Clang tools stuff is an open source project that you're contributing to. I realize the time you have to contribute things may be limited, but the project can't really adjust its code review, design standards, or code quality to work around that. I would encourage you to actually respond to the comments Manuel has provided to the best of your ability in whatever time you're interested in putting into this. Ultimately, before this goes in, *someone* is going to have to do the work to refactor and design this code the right way. Maybe someone else will pick up the patch, but either way, I think the code review stands and it is on you or whomever else to address it. You can't skip that part of the review because you don't have time.</div>
<div><br></div><div>(Now, if I've misunderstood, and you're actually just planning to revisit these issues with a follow-up patch, that's a different matter and sorry for any confusion.)</div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Mon, Aug 4, 2014 at 2:41 PM, Matthew Plant <span dir="ltr"><<a>mplant@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
comments<br>
<div><div><br>
================<br>
Comment at: clang-rename/ClangRename.cpp:159-188<br>
@@ +158,32 @@<br>
+<br>
+ if (PrevName.empty()) {<br>
+ // Retrieve the previous name and USRs.<br>
+ // The source file we are searching will always be the main source file.<br>
+ const auto Point = SourceMgr.getLocForStartOfFile(<br>
+ SourceMgr.getMainFileID()).getLocWithOffset(SymbolOffset);<br>
+ const NamedDecl *TargetDecl = getNamedDeclAt(Context, Point);<br>
+ if (TargetDecl == nullptr) {<br>
+ errs() << "clang-rename: no symbol found at given location\n";<br>
+ *Failed = true;<br>
+ return;<br>
+ }<br>
+<br>
+ // If the decl is in any way related to a class, we want to make sure we<br>
+ // search for the constructor and destructor as well as everything else.<br>
+ if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(TargetDecl))<br>
+ TargetDecl = CtorDecl->getParent();<br>
+ else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(TargetDecl))<br>
+ TargetDecl = DtorDecl->getParent();<br>
+<br>
+ if (const auto *Record = dyn_cast<CXXRecordDecl>(TargetDecl)) {<br>
+ auto ExtraUSRs = getAllConstructorUSRs(Record);<br>
+ USRs.insert(USRs.end(), ExtraUSRs.begin(), ExtraUSRs.end());<br>
+ }<br>
+<br>
+ // Get the primary USR and previous symbol's name.<br>
+ USRs.push_back(getUSRForDecl(TargetDecl));<br>
+ PrevName = TargetDecl->getNameAsString();<br>
+ if (PrintName)<br>
+ errs() << "clang-rename: found symbol: " << PrevName << "\n";<br>
+ }<br>
+<br>
----------------<br>
</div></div><div>Manuel Klimek wrote:<br>
> As mentioned before, I think we want an extra run for this, so it can be called outside the RenamingASTConsumer. It seems completely unrelated to renaming.<br>
</div>I agree, but I cannot refactor this to such a degree in such a short amount of time.<br>
<div><br>
================<br>
Comment at: clang-rename/ClangRename.cpp:201-206<br>
@@ +200,8 @@<br>
+<br>
+ // If we're renaming an operator, we need to fix some of our source<br>
+ // locations.<br>
+ auto OpShortForm = getOpCallShortForm(PrevName);<br>
+ if (!OpShortForm.empty())<br>
+ RenamingCandidates =<br>
+ fixOperatorLocs(OpShortForm, RenamingCandidates, SourceMgr, LangOpts);<br>
+<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> What's the reason not to sink this into getLocationsOfUSR?<br>
</div>Because changing the location is only useful for renaming. If someone wants to use getLocationsOfUSR for anything else, they probably want a different location.<br>
<div><br>
================<br>
Comment at: clang-rename/ClangRename.cpp:215-216<br>
@@ +214,4 @@<br>
+ << FullLoc.getSpellingColumnNumber() << "\n";<br>
+ Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,<br>
+ NewName));<br>
+ }<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> I'd pull that out of the loop and invert the if (PrintLocations) to only affect the errs() <<. Also, I'd probably use outs() unless this is for debugging, in which case we'd want to use the debugging facilities instead of just dumping to stderr...<br>
</div>That would best be left when more of the code is refactored sensibly and renamed locations are easy to extract. At least by printing to stderr the data can be sensibly removed from the output.<br>
<div><br>
================<br>
Comment at: clang-rename/ClangRename.cpp:262<br>
@@ +261,3 @@<br>
+<br>
+ class RenamingFrontendAction : public ASTFrontendAction {<br>
+ public:<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> I'd prefer this class (and everything it uses) to go into its own .h/.cpp file.<br>
> Perhaps call it RenamingAction.h/.cpp.<br>
><br>
> I'd still want to modularize it further:<br>
> - One action to find the USRs (perhaps just export it from USRFinder.h)<br>
> - (mid-term) An AST matcher matchUSRs(const std::vector<std::string>&) that matches when a node matches one of the given USRs; this is non-trival to implement, so I'm fine with having an extra AST consumer for now (the getLocationsOfUSRs seems like a good abstraction for now, but I'd want to add a FIXME)<br>
> - most of the code in RenamingASTConsumer seems non-renaming related; see comments there.<br>
</div>I have done bits of the first parts, but future goals will have to wait until I move back to school<br>
<div><br>
================<br>
Comment at: clang-rename/ClangRename.cpp:283<br>
@@ +282,3 @@<br>
+<br>
+ struct RenamingFactory : public tooling::FrontendActionFactory {<br>
+ RenamingFactory(RenamingFrontendAction *Action) : Action(Action) {<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> You don't actually need this.<br>
> Rename CreateASTConsumer to createASTConsumer, and you'll be able to just say:<br>
> newFrontendActionFactory(&Action)<br>
> below.<br>
</div>that is the weirdest interface in the world.<br>
<div><br>
<br>
================<br>
Comment at: clang-rename/USRFinder.cpp:41<br>
@@ +40,3 @@<br>
+ const SourceLocation Point,<br>
+ const clang::NamedDecl **Result)<br>
+ : SourceMgr(SourceMgr), LangOpts(LangOpts), Point(Point), Result(Result) {<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> I'd prefer giving this class a getResults() method over handing in a NamedDecl**.<br>
</div>Yeah I changed this. Really I think that this could be done a lot better with a few static methods, but I really don't have enough time for that within the next week. It'll have to wait for later in the year.<br>
<div><div><br>
================<br>
Comment at: clang-rename/USRFinder.cpp:101-125<br>
@@ +100,27 @@<br>
+ if (const auto *Decl = Expr->getDirectCallee()) {<br>
+ if (!isa<CXXOperatorCallExpr>(Expr) && (Decl->isOverloadedOperator() ||<br>
+ isa<CXXConversionDecl>(Decl))) {<br>
+ // If we got here, then we found an explicit operator call or<br>
+ // conversion. We fix the range of such calls from the leading 'o' to<br>
+ // the end of the actual operator.<br>
+ const auto *Callee = Expr->getCallee();<br>
+ const auto *MemExpr = dyn_cast<MemberExpr>(Callee);<br>
+ // If this is a member expression, the start location should be after<br>
+ // the '.' or '->'.<br>
+ auto LocStart =<br>
+ ((MemExpr) ? MemExpr->getMemberLoc() : Expr->getLocStart());<br>
+ // getLocEnd returns the start of the last token in the callee<br>
+ // expression. Thus, for 'operator +=', it will return the location of<br>
+ // the '+'.<br>
+ auto OpLoc = Callee->getLocEnd();<br>
+ if (OpLoc.isValid() && OpLoc.isFileID()) {<br>
+ SmallVector<char, 32> Buffer;<br>
+ auto OpName = Lexer::getSpelling(OpLoc, Buffer, SourceMgr, LangOpts);<br>
+ return setResult(Decl, LocStart,<br>
+ OpLoc.getLocWithOffset(OpName.size() - 1));<br>
+ }<br>
+ // If we couldn't get the location of the end of the operator, we just<br>
+ // check in the range of the keyword "operator".<br>
+ return setResult(Decl, LocStart, strlen("operator"));<br>
+ }<br>
+ }<br>
----------------<br>
</div></div><div>Manuel Klimek wrote:<br>
> It's amazing how most of these functions seem to be handling overloaded operators :(<br>
</div>It was decided (not by me) that out of the two things left to possible add before up-streaming - macros and overloaded operators - the latter was to be completed.<br>
<br>
Also, that's not entirely the case - most of the code doesn't, but the code that handles common cases (like operators and variables) are places where operator overloading needs to be accounted for.<br>
<div><br>
================<br>
Comment at: clang-rename/USRFinder.cpp:209-212<br>
@@ +208,6 @@<br>
+ SourceLocation End) {<br>
+ if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||<br>
+ !End.isFileID() || !isPointWithin(Start, End)) {<br>
+ return true;<br>
+ }<br>
+ *Result = Decl;<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> Should we check that Start and End are in the same file?<br>
</div>I guess...<br>
<div><br>
================<br>
Comment at: clang-rename/USRLocFinder.cpp:40-48<br>
@@ +39,11 @@<br>
+<br>
+ bool VisitNamedDecl(const NamedDecl *Decl) {<br>
+ if (getUSRForDecl(Decl) == USR) {<br>
+ // Because we traverse the AST from top to bottom, it follows that the<br>
+ // current locations must be further down (or right) than the previous one<br>
+ // inspected. This has the effect of keeping LocationsFound sorted by<br>
+ // line first column second with no effort of our own.<br>
+ // This is correct as of 2014-06-27<br>
+ LocationsFound.push_back(Decl->getLocation());<br>
+ }<br>
+ return true;<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> I think we either want to test this (which means it will not need a "This is correct as of" comment), or we don't want to rely on it.<br>
</div>We don't rely on it. I'll remove the comment<br>
<div><br>
================<br>
Comment at: test/clang-rename/VarTest.cpp:3<br>
@@ +2,3 @@<br>
+namespace A {<br>
+int /*0*/foo;<br>
+}<br>
----------------<br>
</div><div>Manuel Klimek wrote:<br>
> I'm honestly not sure I like this better than:<br>
> // CHECK: int bar;<br>
</div>This allows us to automatically find the location of the symbol. That way, it checks USRFinder's accuracy as well.<br>
<div><br>
================<br>
Comment at: test/clang-rename/VarTest.cpp:3<br>
@@ +2,3 @@<br>
+namespace A {<br>
+int /*0*/foo;<br>
+}<br>
----------------<br>
</div><div>Matthew Plant wrote:<br>
> Manuel Klimek wrote:<br>
</div><div>> > I'm honestly not sure I like this better than:<br>
> > // CHECK: int bar;<br>
</div>> This allows us to automatically find the location of the symbol. That way, it checks USRFinder's accuracy as well.<br>
this lets the tool automatically find locations. I assure you, it is much easier.<br>
<div><div><br>
<a href="http://reviews.llvm.org/D4739" target="_blank">http://reviews.llvm.org/D4739</a><br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a>cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div>
</blockquote></div>
</blockquote>