diff options
author | Manuel Klimek <klimek@google.com> | 2012-04-26 08:46:12 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2012-04-26 08:46:12 +0000 |
commit | 981d1ec3fd2d33fbb1b47c9fdae9e5a0ea241bc4 (patch) | |
tree | 965bd400849f61a5d8e4bf11367380bf6a74375f | |
parent | 4f148d947c2d864d834070cb9109ef04e726afd9 (diff) |
Reverted unintentional commit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155629 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/RAVFrontendAction.html | 221 | ||||
-rw-r--r-- | examples/PrintFunctionNames/PrintFunctionNames.cpp | 3 |
2 files changed, 1 insertions, 223 deletions
diff --git a/docs/RAVFrontendAction.html b/docs/RAVFrontendAction.html deleted file mode 100644 index dec1166bfa..0000000000 --- a/docs/RAVFrontendAction.html +++ /dev/null @@ -1,221 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<html> -<head> -<title>How to write RecursiveASTVisitor based ASTFrontendActions.</title> -<link type="text/css" rel="stylesheet" href="../menu.css"> -<link type="text/css" rel="stylesheet" href="../content.css"> -</head> -<body> -<div id="content"> - -<h1>How to write RecursiveASTVisitor based ASTFrontendActions.</h1> - -<!-- ======================================================================= --> -<h2 id="intro">Introduction</h2> -<!-- ======================================================================= --> - -In this tutorial you will learn how to create a FrontendAction that uses -a RecursiveASTVisitor to find CXXRecordDecl AST nodes with a specified name. - -<!-- ======================================================================= --> -<h2 id="action">Creating a FrontendAction</h2> -<!-- ======================================================================= --> - -<p>When writing a clang based tool like a Clang Plugin or a standalone tool -based on LibTooling, the common entry point is the FrontendAction. -FrontendAction is an interface that allows execution of user specific actions -as part of the compilation. To run tools over the AST clang provides the -convenience interface ASTFrontendAction, which takes care of executing the -action. The only part left is to implement the CreateASTConsumer method that -returns an ASTConsumer per translation unit.</p> -<pre> - class FindNamedClassAction : public clang::ASTFrontendAction { - public: - virtual clang::ASTConsumer *CreateASTConsumer( - clang::CompilerInstance &Compiler, llvm::StringRef InFile) { - return new FindNamedClassConsumer; - } - }; -</pre> - -<!-- ======================================================================= --> -<h2 id="consumer">Creating an ASTConsumer</h2> -<!-- ======================================================================= --> - -<p>ASTConsumer is an interface used to write generic actions on an AST, -regardless of how the AST was produced. ASTConsumer provides many different -entry points, but for our use case the only one needed is HandleTranslationUnit, -which is called with the ASTContext for the translation unit.</p> -<pre> - class FindNamedClassConsumer : public clang::ASTConsumer { - public: - virtual void HandleTranslationUnit(clang::ASTContext &Context) { - // Traversing the translation unit decl via a RecursiveASTVisitor - // will visit all nodes in the AST. - Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - } - private: - // A RecursiveASTVisitor implementation. - FindNamedClassVisitor Visitor; - }; -</pre> - -<!-- ======================================================================= --> -<h2 id="rav">Using the RecursiveASTVisitor</h2> -<!-- ======================================================================= --> - -<p>Now that everything is hooked up, the next step is to implement a -RecursiveASTVisitor to extract the relevant information from the AST.</p> -<p>The RecursiveASTVisitor provides hooks of the form -bool VisitNodeType(NodeType *) for most AST nodes; the exception are TypeLoc -nodes, which are passed by-value. We only need to implement the methods for the -relevant node types. -</p> -<p>Let's start by writing a RecursiveASTVisitor that visits all CXXRecordDecl's. -<pre> - class FindNamedClassVisitor - : public RecursiveASTVisitor<FindNamedClassVisitor> { - public: - bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) { - // For debugging, dumping the AST nodes will show which nodes are already - // being visited. - Declaration->dump(); - - // The return value indicates whether we want the visitation to proceed. - // Return false to stop the traversal of the AST. - return true; - } - }; -</pre> -</p> -<p>In the methods of our RecursiveASTVisitor we can now use the full power of -the Clang AST to drill through to the parts that are interesting for us. For -example, to find all class declaration with a certain name, we can check for a -specific qualified name: -<pre> - bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) { - if (Declaration->getQualifiedNameAsString() == "n::m::C") - Declaration->dump(); - return true; - } -</pre> -</p> - -<!-- ======================================================================= --> -<h2 id="context">Accessing the SourceManager and ASTContext</h2> -<!-- ======================================================================= --> - -<p>Some of the information about the AST, like source locations and global -identifier information, are not stored in the AST nodes themselves, but in -the ASTContext and its associated source manager. To retrieve them we need to -hand the ASTContext into our RecursiveASTVisitor implementation.</p> -<p>The ASTContext is available from the CompilerInstance during the call -to CreateASTConsumer. We can thus extract it there and hand it into our -freshly created FindNamedClassConsumer:</p> -<pre> - virtual clang::ASTConsumer *CreateASTConsumer( - clang::CompilerInstance &Compiler, llvm::StringRef InFile) { - return new FindNamedClassConsumer(<b>&Compiler.getASTContext()</b>); - } -</pre> - -<p>Now that the ASTContext is available in the RecursiveASTVisitor, we can do -more interesting things with AST nodes, like looking up their source -locations:</p> -<pre> - bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) { - if (Declaration->getQualifiedNameAsString() == "n::m::C") { - // getFullLoc uses the ASTContext's SourceManager to resolve the source - // location and break it up into its line and column parts. - FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart()); - if (FullLocation.isValid()) - llvm::outs() << "Found declaration at " - << FullLocation.getSpellingLineNumber() << ":" - << FullLocation.getSpellingColumnNumber() << "\n"; - } - return true; - } -</pre> - -<!-- ======================================================================= --> -<h2 id="full">Putting it all together</h2> -<!-- ======================================================================= --> - -<p>Now we can combine all of the above into a small example program:</p> -<pre> - #include "clang/AST/ASTConsumer.h" - #include "clang/AST/RecursiveASTVisitor.h" - #include "clang/Frontend/CompilerInstance.h" - #include "clang/Frontend/FrontendAction.h" - #include "clang/Tooling/Tooling.h" - - using namespace clang; - - class FindNamedClassVisitor - : public RecursiveASTVisitor<FindNamedClassVisitor> { - public: - explicit FindNamedClassVisitor(ASTContext *Context) - : Context(Context) {} - - bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) { - if (Declaration->getQualifiedNameAsString() == "n::m::C") { - FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart()); - if (FullLocation.isValid()) - llvm::outs() << "Found declaration at " - << FullLocation.getSpellingLineNumber() << ":" - << FullLocation.getSpellingColumnNumber() << "\n"; - } - return true; - } - - private: - ASTContext *Context; - }; - - class FindNamedClassConsumer : public clang::ASTConsumer { - public: - explicit FindNamedClassConsumer(ASTContext *Context) - : Visitor(Context) {} - - virtual void HandleTranslationUnit(clang::ASTContext &Context) { - Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - } - private: - FindNamedClassVisitor Visitor; - }; - - class FindNamedClassAction : public clang::ASTFrontendAction { - public: - virtual clang::ASTConsumer *CreateASTConsumer( - clang::CompilerInstance &Compiler, llvm::StringRef InFile) { - return new FindNamedClassConsumer(&Compiler.getASTContext()); - } - }; - - int main(int argc, char **argv) { - if (argc > 1) { - clang::tooling::runToolOnCode(new FindNamedClassAction, argv[1]); - } - } -</pre> - -<p>We store this into a file called FindClassDecls.cpp and create the following -CMakeLists.txt to link it:</p> -<pre> -set(LLVM_USED_LIBS clangTooling) - -add_clang_executable(find-class-decls FindClassDecls.cpp) -</pre> - -<p>When running this tool over a small code snippet it will output all -declarations of a class n::m::C it found:</p> -<pre> - $ ./bin/find-class-decls "namespace n { namespace m { class C {}; } }" - Found declaration at 1:29 -</pre> - -</div> -</body> -</html> - diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp index b024b968db..ce8f208e41 100644 --- a/examples/PrintFunctionNames/PrintFunctionNames.cpp +++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -17,7 +17,6 @@ #include "clang/AST/AST.h" #include "clang/Frontend/CompilerInstance.h" #include "llvm/Support/raw_ostream.h" -#include "clang/Frontend/FrontendActions.h" using namespace clang; namespace { @@ -68,5 +67,5 @@ protected: } -static FrontendPluginRegistry::Add<SyntaxOnlyAction> +static FrontendPluginRegistry::Add<PrintFunctionNamesAction> X("print-fns", "print function names"); |