Why getTranslationUnitDecl is NULL in ASTConsumer when running in cling?

Hi,

I have a file test.cpp:

#include "clang/Driver/Options.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Rewrite/Core/Rewriter.h"

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

class ExampleASTConsumer : public ASTConsumer {
public:
    explicit ExampleASTConsumer(CompilerInstance *CI) {
    }

    virtual void HandleTranslationUnit(ASTContext &Context) {
      errs() << "Context: " << &Context << "\ngetTranslationUnitDecl: " << Context.getTranslationUnitDecl() << "\n";
      // Why is getTranslationUnitDecl==0x0?  Without getTranslationUnitDecl, I can't call:
      //  visitor->TraverseDecl(Context.getTranslationUnitDecl());
    }
};
class ExampleFrontendAction : public ASTFrontendAction {
public:
    std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) {
        return llvm::make_unique<ExampleASTConsumer>(&CI);
    }
};
static cl::OptionCategory testCategory("test options");

Then in cling, I load and run these:

.L libclangRewrite.so
.L libclangASTMatchers.so
.L libclangTooling.so
.L test.cpp

int argc=2;
const char *argv[]={"example","test.cpp","--"};
CommonOptionsParser op(argc, argv, testCategory);
ClangTool Tool(op.getCompilations(), op.getSourcePathList());
std::unique_ptr<FrontendActionFactory> FrontendFactory;
FrontendFactory = newFrontendActionFactory<ExampleFrontendAction>();
int result = Tool.run(FrontendFactory.get());

and then cling prints out that the getTranslationUnitDecl == 0x0:

Context: 0x7822740
getTranslationUnitDecl: 0x0

Do you know why getTranslationUnitDecl==0x0? Without getTranslationUnitDecl, I can’t
traverse the AST with “visitor->TraverseDecl(Context.getTranslationUnitDecl());”

Thank you.

Hi,
I am not sure what you want to do. If you want to visit the translation unit of some code why not creating a clang plugin: clang.llvm.org/docs/ClangPlugins.html There are quite a lot of demos on the internet.

If you still want to do it within cling. Please have a look at the interpreter callbacks: cling.web.cern.ch/cling/doxygen/ … backs.html You can create your custom callback and subscribe to “interesting” events.

It should be something like:

[cling] #include "cling/Interpreter/InterpreterCallbacks.h"
[cling] class MyInterpreterCallbacks: public InterpreterCallbacks {...}
[cling] #include "cling/Interpreter/Interpreter.h"
[cling] gCling->setCallbacks(new MyInterpreterCallbacks());

Please note this is supposed to be pseudo-code :wink:

–Vassil

Thank you for pointing out about “interpreter callbacks” method.

I am trying to learn clang AST and was trying to run this example:

kevinaboos.wordpress.com/2013/0 … g-example/

in cling; is it possible to duplicate this example using cling’s “interpreter callbacks” method?
Using the “interpreter callbacks” method, what is the equivalent to this example’s:

Tool.run(FrontendFactory.get());

Thank you.

I think it is possible, but the example should be changed quite a lot.

Another way of learning clang’s AST is clang++ …args… -Xclang -ast-dump

–Vassil