Finding variables in Cling

Is it possible to return the name and type of all variables that have been defined in a cling::Interpreter instance (like the example in llvm/tools/cling/tools/demo/cling-demo.cpp) using the Cling API?

They are all global, so you’d have to look at all clang::VarDecls in the clang::TranslationUnitDecl.

Grab any clang::Decl (e.g. from any cling::Transaction), get the clang::TranslationUnitDecl from it and iterate. You’re looking for all clang::VarDecls that are defined in “files” that are included by the top-most cling “file”. Use clang::Decl::getLocation() to get the SourceLocation and then the clang::SourceManager (e.g. getIncludeLoc()) to make sense of which kind of buffer it is. To be sufficiently close you could even just look at the name of the “files” where the variable is defined; if it starts with “input_line_” then the variable definition would be part of the interactive session.

Thank you so much. I would never figure that out by myself. I actually though cling::Interpreter kept track of these variables.

I got the transaction from my instance and got to iterate the VarDecls. I had trouble getting the source manager though:

    const cling::Transaction* t = interp.getLatestTransaction();
    clang::DeclGroupRef d = t->getCurrentLastDecl();
    clang::Decl* d2 = d.getSingleDecl();
    clang::TranslationUnitDecl* tu = d2->getTranslationUnitDecl();
    clang::DeclContext::decl_iterator it;
    for (it = tu->decls_begin();it != tu->decls_end(); ++it){
        // how do I construct the SourceManager?
        clang::SourceManager sm;
        // Or does SourceLocation has a function that returns its SourceManager?
        it->getLocation().dump(sm);
        // sm.getIncludeLoc();
    }

How do I construct the SourceManager? Or does SourceLocation has a function that returns its SourceManager?

clang::SourceManager& s = d2->getASTContext().getSourceManager();

Thanks! Getting there.

    const cling::Transaction* t = interp.getLatestTransaction();
    clang::DeclGroupRef d = t->getCurrentLastDecl();
    clang::Decl* d2 = d.getSingleDecl();
    clang::TranslationUnitDecl* tu = d2->getTranslationUnitDecl();
    clang::SourceManager& sm = d2->getASTContext().getSourceManager();
    clang::DeclContext::decl_iterator it;
    for (it = tu->decls_begin();it != tu->decls_end(); ++it) {
        clang::SourceLocation sl = it->getLocation();
        std::cout << sl.printToString(sm) << " Kind: " << it->getKind() << " DeclKind: " << it->getDeclKindName() << std::endl;
    }

Where is the variable name now?

if (const VarDecl* vd = dyn_cast<VarDecl>(*it)) {
   std::cout << vd->getName().str() << std::endl;
}

Done. Thanks again!

    cling::Interpreter interp(argc, argv, LLVMDIR);
    // ...
    const cling::Transaction* t = interp.getLatestTransaction();
    clang::DeclGroupRef d = t->getCurrentLastDecl();
    clang::Decl* d2 = d.getSingleDecl();
    clang::TranslationUnitDecl* tu = d2->getTranslationUnitDecl();
    clang::SourceManager& sm = d2->getASTContext().getSourceManager();
    clang::DeclContext::decl_iterator it;
    for (it = tu->decls_begin();it != tu->decls_end(); ++it) {
        clang::SourceLocation sl = it->getLocation();
        if (sl.printToString(sm).substr(0,11) == "input_line_"){
            if (const clang::VarDecl* vd = clang::dyn_cast<clang::VarDecl>(*it)) {
                std::cout << sl.printToString(sm) << "\t"
                          << it->getDeclKindName() << "\t"
                          << vd->getName().str() << "\t"
                          << vd->getType().getAsString() << std::endl;
            }
        }
    }

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.