<div dir="ltr">Shouldn't be... you also don't have overly unspecific matchers... I'd be curious about some profiling in your case...</div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jul 16, 2015 at 12:07 PM Han Wang <<a href="mailto:wanghan02@gmail.com">wanghan02@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">We use truly a lot of templates in the files. Is it a possible reason why it's so slow? </div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 16, 2015 at 11:57 AM, Han Wang <span dir="ltr"><<a href="mailto:wanghan02@gmail.com" target="_blank">wanghan02@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Manuel, <div><br></div><div>After using -O2 the speed is 30% faster from 10min to 7min. If I use clang to just compile this source file, it takes 40sec. </div><div><br></div><div>Best regards, </div><span><font color="#888888"><div>Han</div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 16, 2015 at 11:33 AM, Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">You'll want to use Lexer::getSourceText instead of trying to write your own (trust me, it's hard ;), but otherwise your code looks innocent enough. Are you compiling with at least -O2 and NDEBUG enabled?</div><div><div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jul 16, 2015 at 11:26 AM Han Wang <<a href="mailto:wanghan02@gmail.com" target="_blank">wanghan02@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><font face="monospace, monospace" size="1">#include <stdio.h></font></div><div><font face="monospace, monospace" size="1">#include <string></font></div><div><font face="monospace, monospace" size="1">#include <vector></font></div><div><font face="monospace, monospace" size="1">#include <system_error></font></div><div><font face="monospace, monospace" size="1">#include <type_traits></font></div><div><font face="monospace, monospace" size="1">#include "clang/AST/AST.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Frontend/TextDiagnosticPrinter.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Tooling/CommonOptionsParser.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/ASTMatchers/ASTMatchers.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/ASTMatchers/ASTMatchFinder.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Basic/SourceManager.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Frontend/FrontendActions.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Lex/Lexer.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Tooling/CompilationDatabase.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Tooling/Refactoring.h"</font></div><div><font face="monospace, monospace" size="1">#include "clang/Tooling/Tooling.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/ADT/Twine.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/Support/CommandLine.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/Support/MemoryBuffer.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/Support/Path.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/Support/Signals.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/Support/raw_ostream.h"</font></div><div><font face="monospace, monospace" size="1">#include "llvm/Support/TargetSelect.h"</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">using namespace llvm;</font></div><div><font face="monospace, monospace" size="1">using clang::tooling::newFrontendActionFactory;</font></div><div><font face="monospace, monospace" size="1">using clang::tooling::Replacement;</font></div><div><font face="monospace, monospace" size="1">using clang::tooling::CompilationDatabase;</font></div><div><font face="monospace, monospace" size="1">using namespace clang;</font></div><div><font face="monospace, monospace" size="1">using namespace clang::ast_matchers;</font></div><div><font face="monospace, monospace" size="1">using namespace clang::driver;</font></div><div><font face="monospace, monospace" size="1">using namespace clang::tooling;</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">static llvm::cl::OptionCategory ToolingSampleCategory("IsEmpty");</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">// Returns the text that makes up 'node' in the source.</font></div><div><font face="monospace, monospace" size="1">// Returns an empty string if the text cannot be found.</font></div><div><font face="monospace, monospace" size="1">template <typename T></font></div><div><font face="monospace, monospace" size="1">static std::string getText(const SourceManager &SourceManager, const T &Node) {</font></div><div><font face="monospace, monospace" size="1"> SourceLocation StartSpellingLocation =</font></div><div><font face="monospace, monospace" size="1"> SourceManager.getSpellingLoc(Node.getLocStart());</font></div><div><font face="monospace, monospace" size="1"> SourceLocation EndSpellingLocation =</font></div><div><font face="monospace, monospace" size="1"> SourceManager.getSpellingLoc(Node.getLocEnd());</font></div><div><font face="monospace, monospace" size="1"> if (!StartSpellingLocation.isValid() || !EndSpellingLocation.isValid()) {</font></div><div><font face="monospace, monospace" size="1"> return std::string();</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1"> bool Invalid = true;</font></div><div><font face="monospace, monospace" size="1"> const char *Text =</font></div><div><font face="monospace, monospace" size="1"> SourceManager.getCharacterData(StartSpellingLocation, &Invalid);</font></div><div><font face="monospace, monospace" size="1"> if (Invalid) {</font></div><div><font face="monospace, monospace" size="1"> return std::string();</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1"> std::pair<FileID, unsigned> Start =</font></div><div><font face="monospace, monospace" size="1"> SourceManager.getDecomposedLoc(StartSpellingLocation);</font></div><div><font face="monospace, monospace" size="1"> std::pair<FileID, unsigned> End =</font></div><div><font face="monospace, monospace" size="1"> SourceManager.getDecomposedLoc(Lexer::getLocForEndOfToken(</font></div><div><font face="monospace, monospace" size="1"> EndSpellingLocation, 0, SourceManager, LangOptions()));</font></div><div><font face="monospace, monospace" size="1"> if (Start.first != End.first) {</font></div><div><font face="monospace, monospace" size="1"> // Start and end are in different files.</font></div><div><font face="monospace, monospace" size="1"> return std::string();</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1"> if (End.second < Start.second) {</font></div><div><font face="monospace, monospace" size="1"> // Shuffling text with macros may cause this.</font></div><div><font face="monospace, monospace" size="1"> return std::string();</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1"> return std::string(Text, End.second - Start.second);</font></div><div><font face="monospace, monospace" size="1">}</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">class ColIsEmptyHandler: public MatchFinder::MatchCallback {</font></div><div><font face="monospace, monospace" size="1">public:</font></div><div><font face="monospace, monospace" size="1"> ColIsEmptyHandler(Replacements *Replace): Replace(Replace) {};</font></div><div><font face="monospace, monospace" size="1"> virtual void run(const MatchFinder::MatchResult &Result) {</font></div><div><font face="monospace, monospace" size="1"> if (const CXXMemberCallExpr *callExpr = Result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("Col::IsEmptyExpr")) {</font></div><div><span style="font-family:monospace,monospace;font-size:x-small"> const std::string text = getText(*(Result.SourceManager), *callExpr); </span><br></div><div><span style="font-family:monospace,monospace;font-size:x-small"> Replacement Rep(*(Result.SourceManager), CharSourceRange::getTokenRange(SourceRange(callExpr->getCallee()->getExprLoc())), "IsEmpty");</span><br></div><div><font face="monospace, monospace" size="1"> Replace->insert(Rep);</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1">private:</font></div><div><font face="monospace, monospace" size="1"> Replacements *Replace; </font></div><div><font face="monospace, monospace" size="1">};</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">class ColIsEmptyInClassHandler: public MatchFinder::MatchCallback {</font></div><div><font face="monospace, monospace" size="1">public:</font></div><div><font face="monospace, monospace" size="1"> ColIsEmptyInClassHandler(Replacements *Replace): Replace(Replace) {};</font></div><div><font face="monospace, monospace" size="1"> virtual void run(const MatchFinder::MatchResult &Result) {</font></div><div><font face="monospace, monospace" size="1"> if (const CXXMethodDecl *decl = Result.Nodes.getNodeAs<clang::CXXMethodDecl>("Col::IsEmptyInClass")) {</font></div><div><span style="font-family:monospace,monospace;font-size:x-small"> const std::string text = getText(*(Result.SourceManager), *decl); </span><br></div><div><font face="monospace, monospace" size="1"> Replacement Rep(*(Result.SourceManager), CharSourceRange::getTokenRange(SourceRange(decl->getNameInfo().getLoc())), "IsEmpty");</font></div><div><font face="monospace, monospace" size="1"> Replace->insert(Rep);</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1"> }</font></div><div><font face="monospace, monospace" size="1">private:</font></div><div><font face="monospace, monospace" size="1"> Replacements *Replace; </font></div><div><font face="monospace, monospace" size="1">};</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">int main(int argc, const char **argv) {</font></div><div><font face="monospace, monospace" size="1"> llvm::InitializeAllTargets();</font></div><div><font face="monospace, monospace" size="1"> llvm::InitializeAllTargetMCs();</font></div><div><font face="monospace, monospace" size="1"> llvm::InitializeAllAsmPrinters();</font></div><div><font face="monospace, monospace" size="1"> llvm::InitializeAllAsmParsers();<span style="white-space:pre-wrap"> </span></font></div><div><font face="monospace, monospace" size="1"> CommonOptionsParser op(argc, argv, ToolingSampleCategory);</font></div><div><font face="monospace, monospace" size="1"> RefactoringTool Tool(op.getCompilations(), op.getSourcePathList());</font></div><div><font face="monospace, monospace" size="1"> // Set up AST matcher callbacks.</font></div><div><font face="monospace, monospace" size="1"> ColIsEmptyHandler HandlerForColIsEmpty(&Tool.getReplacements());</font></div><div><font face="monospace, monospace" size="1"> ColIsEmptyInClassHandler HandlerForColIsEmptyInClass(&Tool.getReplacements());</font></div><div><font face="monospace, monospace" size="1"> MatchFinder Finder;</font></div><div><font face="monospace, monospace" size="1"> Finder.addMatcher(memberCallExpr(hasDeclaration(methodDecl(</font></div><div><font face="monospace, monospace" size="1"> <span style="white-space:pre-wrap"> </span>hasName("Empty"), ofClass(isSameOrDerivedFrom(hasName("Col")))))).bind("Col::IsEmptyExpr"), &HandlerForColIsEmpty);</font></div><div><font face="monospace, monospace" size="1"> Finder.addMatcher(methodDecl(hasName("Empty"), ofClass(isSameOrDerivedFrom(hasName("Col")))).bind("Col::IsEmptyInClass"), &HandlerForColIsEmptyInClass);</font></div><div><font face="monospace, monospace" size="1"> // Run the tool and collect a list of replacements.</font></div><div><font face="monospace, monospace" size="1"> if (int Result = Tool.runAndSave(newFrontendActionFactory(&Finder).get())) {</font></div><div><font face="monospace, monospace" size="1"> return Result;</font></div><div><font face="monospace, monospace" size="1"> } </font></div><div><font face="monospace, monospace" size="1"> llvm::outs() << "Replacements collected by the tool:\n";</font></div><div><font face="monospace, monospace" size="1"> for (auto &r : Tool.getReplacements()) {</font></div><div><font face="monospace, monospace" size="1"> llvm::outs() << r.toString() << "\n";</font></div><div><font face="monospace, monospace" size="1"> } </font></div><div><font face="monospace, monospace" size="1"> return 0;</font></div></div><div dir="ltr"><div><font face="monospace, monospace" size="1">}</font></div><div class="gmail_extra"><font face="monospace, monospace" size="1"><br></font><div class="gmail_quote"><font face="monospace, monospace" size="1">On Thu, Jul 16, 2015 at 11:11 AM, Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>></span> wrote:<br></font><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><font face="monospace, monospace" size="1">Can you post the code for the matcher?</font></div><font face="monospace, monospace" size="1"><br></font><div class="gmail_quote"><div><div><div dir="ltr"><font face="monospace, monospace" size="1">On Thu, Jul 16, 2015 at 11:02 AM Han Wang <<a href="mailto:wanghan02@gmail.com" target="_blank">wanghan02@gmail.com</a>> wrote:<br></font></div></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div dir="ltr"><font face="monospace, monospace" size="1">Hi, </font><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">I'm using clang AST matcher tool on MAC to analyse complex files with many many headers included. It turns out that it takes more than 10 times longer than just compile the same file with clang. Is it normal or am I doing something wrong? Thanks!</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">Best regards,</font></div><div><font face="monospace, monospace" size="1">Han</font></div></div></div></div><font face="monospace, monospace" size="1">
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</font></blockquote></div>
</blockquote></div><br></div></div></blockquote></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</blockquote></div>