diff --git a/clang/docs/RAVFrontendAction.html b/clang/docs/RAVFrontendAction.html deleted file mode 100644 index dec1166bfac5..000000000000 --- a/clang/docs/RAVFrontendAction.html +++ /dev/null @@ -1,221 +0,0 @@ - - - -How to write RecursiveASTVisitor based ASTFrontendActions. - - - - -
- -

How to write RecursiveASTVisitor based ASTFrontendActions.

- - -

Introduction

- - -In this tutorial you will learn how to create a FrontendAction that uses -a RecursiveASTVisitor to find CXXRecordDecl AST nodes with a specified name. - - -

Creating a FrontendAction

- - -

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.

-
-  class FindNamedClassAction : public clang::ASTFrontendAction {
-  public:
-    virtual clang::ASTConsumer *CreateASTConsumer(
-      clang::CompilerInstance &Compiler, llvm::StringRef InFile) {
-      return new FindNamedClassConsumer;
-    }
-  };
-
- - -

Creating an ASTConsumer

- - -

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.

-
-  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;
-  };
-
- - -

Using the RecursiveASTVisitor

- - -

Now that everything is hooked up, the next step is to implement a -RecursiveASTVisitor to extract the relevant information from the AST.

-

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. -

-

Let's start by writing a RecursiveASTVisitor that visits all CXXRecordDecl's. -

-  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;
-    }
-  };
-
-

-

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: -

-  bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {
-    if (Declaration->getQualifiedNameAsString() == "n::m::C")
-      Declaration->dump();
-    return true;
-  }
-
-

- - -

Accessing the SourceManager and ASTContext

- - -

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.

-

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:

-
-  virtual clang::ASTConsumer *CreateASTConsumer(
-    clang::CompilerInstance &Compiler, llvm::StringRef InFile) {
-    return new FindNamedClassConsumer(&Compiler.getASTContext());
-  }
-
- -

Now that the ASTContext is available in the RecursiveASTVisitor, we can do -more interesting things with AST nodes, like looking up their source -locations:

-
-  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;
-  }
-
- - -

Putting it all together

- - -

Now we can combine all of the above into a small example program:

-
-  #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]);
-    }
-  }
-
- -

We store this into a file called FindClassDecls.cpp and create the following -CMakeLists.txt to link it:

-
-set(LLVM_USED_LIBS clangTooling)
-
-add_clang_executable(find-class-decls FindClassDecls.cpp)
-
- -

When running this tool over a small code snippet it will output all -declarations of a class n::m::C it found:

-
-  $ ./bin/find-class-decls "namespace n { namespace m { class C {}; } }"
-  Found declaration at 1:29
-
- -
- - - diff --git a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp index b024b968dbce..ce8f208e41de 100644 --- a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp +++ b/clang/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 +static FrontendPluginRegistry::Add X("print-fns", "print function names");