Clang LibTooling - How to use DependencyCollector

352 views Asked by At

I'm trying to use the DependencyCollector class of Clang in my Tool to list all the dependencies in a file, lets say test.cpp
Here is my program:

#include "stdafx.h"
#include <iostream>
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"

using namespace std;
using namespace clang::tooling;
using namespace clang;
using namespace llvm;

static cl::OptionCategory MyToolCategory("my-tool options");
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::extrahelp MoreHelp("\nMore help text...");

class myDependencyCollector : public DependencyCollector {
private:
public:
    bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing) {
        if (Filename == "stdafx.h" || IsSystem) { 
            return false; 
        } else {
            return true;
        }
    }
    bool needSystemDependencies() {
        return false;
    }
};

class DependencyAction : public PreprocessOnlyAction {
private:
    myDependencyCollector *col;
public:
    virtual bool usesPreprocessOnly() const {
        return true;
    }
    bool BeginSourceFileAction(CompilerInstance &ci) {
        Preprocessor &pp = ci.getPreprocessor();
        col = new myDependencyCollector();
        col->attachToPreprocessor(pp);
        return true;
    }

    void ExecuteAction() {
    }

    virtual void EndSourceFileAction() {
        llvm::ArrayRef<string> arr = col->getDependencies();
        int size = arr.size();
        for (int i = 0; i < size; i = i+1) {
            cout << arr[i] << endl;
        }
    }
};

int main(int argc, const char **argv)
{
    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
    ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList());
    int result = Tool.run(newFrontendActionFactory<DependencyAction>().get());
    return result;
}

Now, if I run the program on, for example the file test.cpp:

#include <iostream>
#include "test.h"
void do_math(int *x) {
    *x += 5;
}

int main(void) {
    int result = -1, val = 4;
    do_math(&val);
    return result;
}

The program doesn't find any includes.
It would be great if anybody could help me because I have not been able to find an answer after hours of searching on the internet.

1

There are 1 answers

0
mpeschke On

The problem is that you overwrite the ExecuteAction() method from class PreprocessOnlyAction with an empty body. If you delete the line:

void ExecuteAction() {}

everything works as expected.