14

In common IDEs (pick one) you often have an outline view showing you the list of methods for a specific class.

Suppose I have a C++ interface class in IFoo.h that looks like this:

#ifndef IFOO_H_
#define IFOO_H_
class IFoo { 
    public:
        virtual ~IFoo() {}
        virtual void bar() = 0;
};
#endif

How (programmatically) can I get such an IDE outliner list for my IFoo.h file above using maybe the clang libraries? For a first start, it would help if I can get a list of names of functions.

I specifically intend to use clang, so any help on how to analyze the my header file with clang would be really appreciated.

Meanwhile I will have a look at the clang tutorial here: https://github.com/loarabia/Clang-tutorial

Thanks in advance for your help.

1 Answer 1

18

I went through this tutorial http://clang.llvm.org/docs/LibASTMatchersTutorial.html and found some pretty helpful stuff there, this is what I came up with:

I had to rename my file from IFoo.h to IFoo.hpp to be detected as Cxx and not C code.

I had to call my program with -x c++ to have my IFoo.h file being recognized as C++ code rather than C code (clang interprets *.h files as C by default:

~/Development/llvm-build/bin/mytool ~/IFoo.h -- -x c++

This is my code to dump all virtual functions from the provided class:

// Declares clang::SyntaxOnlyAction.
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/ASTMatchers/ASTMatchers.h"
// Declares llvm::cl::extrahelp.
#include "llvm/Support/CommandLine.h"

#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

#include <cstdio>

using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace llvm;

DeclarationMatcher methodMatcher = methodDecl(isVirtual()).bind("methods");

class MethodPrinter : public MatchFinder::MatchCallback {
public :
  virtual void run(const MatchFinder::MatchResult &Result) {
    if (const CXXMethodDecl *md = Result.Nodes.getNodeAs<clang::CXXMethodDecl>("methods")) {    
      md->dump();
    }
  }
};

// CommonOptionsParser declares HelpMessage with a description of the common
// command-line options related to the compilation database and input files.
// It's nice to have this help message in all tools.
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);

// A help message for this specific tool can be added afterwards.
static cl::extrahelp MoreHelp("\nMore help text...");

int main(int argc, const char **argv) {    
  cl::OptionCategory cat("myname", "mydescription");
  CommonOptionsParser optionsParser(argc, argv, cat, 0);    

  ClangTool tool(optionsParser.getCompilations(), optionsParser.getSourcePathList());

  MethodPrinter printer;
  MatchFinder finder;
  finder.addMatcher(methodMatcher, &printer);
  return tool.run(newFrontendActionFactory(&finder));
}

The output looks like this, when passed the IFoo.h file:

CXXDestructorDecl 0x1709c30 <~/IFoo.h:5:3, col:20> ~IFoo 'void (void)' virtual
`-CompoundStmt 0x1758128 <col:19, col:20>
CXXMethodDecl 0x1757e60 <~/IFoo.h:6:3, col:24> bar 'void (void)' virtual pure
Sign up to request clarification or add additional context in comments.

3 Comments

Did you investigate how to inspect methods of a particular access level? I'm not sure exactly how to only inspect public methods. Specifically, I need the location of the last public method.
I will show you how to do it when Im back at my computer later today or tomorrow morning. I only have a cellphone at hand right now.
I posted this as a question here: stackoverflow.com/questions/24564494/… if you'd like to answer. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.