<div dir="ltr">In general, getting clang to parse code with the code you have is hard :) That's why we have a tooling library to make that a lot easier. You can either use that directly, or look at the implementation to get hints around what you're doing wrong. My guess is that you're not using C++ mode ('namespace' error) and don't go through the driver's include directory detection.<div>
<br></div><div style>See:</div><div style><a href="http://clang.llvm.org/docs/LibTooling.html">http://clang.llvm.org/docs/LibTooling.html</a><br></div><div style><br></div><div style>The implementation is here:</div><div style>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?view=markup">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?view=markup</a><br></div><div style><br></div><div style>Cheers,</div>
<div style>/Manuel</div><div style><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Mar 17, 2013 at 4:04 PM, suppamax <span dir="ltr"><<a href="mailto:max.giacometti@gmail.com" target="_blank">max.giacometti@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Sorry, after posting I identified a stupid mistake. I have to reformulate the<br>
question:<br>
<div class="im"><br>
<br>
<br>
I'd like to scan clang's AST. I started using some sample code provided in<br>
one tutorial.<br>
<br>
My current code is<br>
<br>
</div><div><div class="h5">#include <iostream><br>
<br>
#include "llvm/Support/raw_ostream.h"<br>
#include "llvm/Support/Host.h"<br>
#include "llvm/Support/Casting.h"<br>
<br>
#include "clang/Basic/DiagnosticOptions.h"<br>
#include "clang/Frontend/TextDiagnosticPrinter.h"<br>
<br>
#include "clang/Basic/LangOptions.h"<br>
#include "clang/Basic/FileSystemOptions.h"<br>
<br>
#include "clang/Basic/SourceManager.h"<br>
#include "clang/Lex/HeaderSearch.h"<br>
#include "clang/Basic/FileManager.h"<br>
<br>
#include "clang/Frontend/Utils.h"<br>
<br>
#include "clang/Basic/TargetOptions.h"<br>
#include "clang/Basic/TargetInfo.h"<br>
#include "clang/Basic/Version.h"<br>
<br>
#include "clang/Lex/Preprocessor.h"<br>
#include "clang/Frontend/FrontendOptions.h"<br>
<br>
#include "clang/Basic/IdentifierTable.h"<br>
#include "clang/Basic/Builtins.h"<br>
<br>
#include "clang/AST/ASTContext.h"<br>
#include "clang/AST/ASTConsumer.h"<br>
#include "clang/AST/RecursiveASTVisitor.h"<br>
#include "clang/Sema/Sema.h"<br>
#include "clang/AST/DeclBase.h"<br>
#include "clang/AST/Type.h"<br>
#include "clang/AST/Decl.h"<br>
#include "clang/Sema/Lookup.h"<br>
#include "clang/Sema/Ownership.h"<br>
#include "clang/AST/DeclGroup.h"<br>
<br>
#include "clang/Parse/Parser.h"<br>
<br>
#include "clang/Parse/ParseAST.h"<br>
#include "clang/Frontend/CompilerInstance.h"<br>
<br>
#include "clang/Rewrite/Core/Rewriter.h"<br>
#include "clang/Rewrite/Frontend/Rewriters.h"<br>
<br>
using namespace clang;<br>
using namespace std;<br>
<br>
// By implementing RecursiveASTVisitor, we can specify which AST nodes<br>
// we're interested in by overriding relevant methods.<br>
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor><br>
{<br>
public:<br>
//  MyASTVisitor() : {}<br>
//  MyASTVisitor(Rewriter &R)<br>
//      : TheRewriter(R)<br>
//  {}<br>
<br>
    bool VisitStmt(clang::Stmt *s) {<br>
//      llvm::errs() << "Visiting statement\n";<br>
//      if (clang::isa<clang::BinaryOperator>(s)) {<br>
//          if (cast<BinaryOperator>(s)->isAssignmentOp() == true) {<br>
//              // blablabla<br>
//          }<br>
//      }<br>
        return true;<br>
    }<br>
<br>
    bool VisitBinaryOperator(BinaryOperator* bo) {<br>
        if (bo->isAssignmentOp() == true) {<br>
            llvm::errs() << "Visiting assignment ";<br>
            Expr *LHS;<br>
            LHS = bo->getLHS();<br>
            DeclRefExpr* dre;<br>
            if ((dre = dyn_cast<DeclRefExpr>(LHS))) {<br>
                string name = (dre->getNameInfo()).getName().getAsString();<br>
                llvm::errs() << "to " << name;<br>
            }<br>
            if (ArraySubscriptExpr* ase = dyn_cast<ArraySubscriptExpr>(LHS))<br>
{<br>
                Expr *arrayBase = ase->getBase()->IgnoreParenCasts();<br>
                if ((dre = dyn_cast<DeclRefExpr>(arrayBase))) {<br>
                    string name =<br>
(dre->getNameInfo()).getName().getAsString();<br>
                    llvm::errs() << "to array " << name;<br>
                }<br>
            }<br>
            llvm::errs() << "\n";<br>
        }<br>
        return true;<br>
    }<br>
<br>
    bool shouldVisitTemplateInstantiations() const {<br>
        llvm::errs() << "PIPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" <<<br>
"\n";<br>
        return true; }<br>
<br>
    bool VisitCXXOperatorCallExprs(CXXOperatorCallExpr *e) {<br>
        llvm::errs() << "Visiting cxxoperatorcall" << "\n";<br>
        return true;<br>
    }<br>
<br>
    bool VisitCXXConstructorDecl(CXXConstructorDecl *c) {<br>
        llvm::errs() << "Visiting CXXConstructorDecl" << "\n";<br>
        return true;<br>
    }<br>
<br>
    bool VisitDeclRefExpr(DeclRefExpr* expr) {<br>
        string name = (expr->getNameInfo()).getName().getAsString();<br>
        llvm::errs() << name << "\n";<br>
        return true;<br>
    }<br>
<br>
    bool VisitVarDecl(VarDecl *v) {<br>
        llvm::errs() << "Visiting declaration of variable " <<<br>
v->getDeclName().getAsString() << "\n";<br>
        llvm::errs() << "  type: " <<<br>
v->getTypeSourceInfo()->getType().getTypePtr()->getTypeClassName();<br>
        if (v->getTypeSourceInfo()->getType().getTypePtr()->isFloatingType()<br>
== true) {<br>
            llvm::errs() << " -> float";<br>
        }<br>
<br>
if(v->getTypeSourceInfo()->getType().getTypePtr()->isConstantArrayType() ==<br>
true) {<br>
            llvm::errs() << " of ";<br>
            llvm::errs() << v->getTypeSourceInfo()->getType().getAsString();<br>
            llvm::errs() << " size ";<br>
            llvm::APInt arraySize =<br>
cast<ConstantArrayType>(v->getTypeSourceInfo()->getType().getTypePtr())->getSize();<br>
            llvm::errs() << arraySize;<br>
        }<br>
        if(v->getTypeSourceInfo()->getType().getTypePtr()->isPointerType()<br>
== true) {<br>
            llvm::errs() << " to " <<<br>
v->getTypeSourceInfo()->getType().getAsString();<br>
<br>
        }<br>
        llvm::errs() << "\n";<br>
        return true;<br>
    }<br>
<br>
  bool VisitTypedefDecl(clang::TypedefDecl *d) {<br>
        llvm::errs() << "Visiting " << d->getDeclKindName() << " " <<<br>
d->getName() << "\n";<br>
<br>
        return true; // returning false aborts the traversal<br>
    }<br>
<br>
    bool VisitFunctionDecl(FunctionDecl *f) {<br>
        llvm::errs() << "Visiting function " <<<br>
f->getNameInfo().getName().getAsString() << "\n";<br>
<br>
        return true;<br>
    }<br>
<br>
<br>
<br>
private:<br>
//  Rewriter &TheRewriter;<br>
};<br>
<br>
<br>
// Implementation of the ASTConsumer interface for reading an AST produced<br>
// by the Clang parser.<br>
class MyASTConsumer : public ASTConsumer<br>
{<br>
public:<br>
    MyASTConsumer() : Visitor() {}<br>
//  MyASTConsumer(Rewriter &R)<br>
//      : Visitor(R)<br>
//  {}<br>
<br>
    // Override the method that gets called for each parsed top-level<br>
    // declaration.<br>
    virtual bool HandleTopLevelDecl(DeclGroupRef DR) {<br>
        for (DeclGroupRef::iterator b = DR.begin(), e = DR.end();<br>
                 b != e; ++b)<br>
            // Traverse the declaration using our AST visitor.<br>
            Visitor.TraverseDecl(*b);<br>
        return true;<br>
    }<br>
<br>
private:<br>
    MyASTVisitor Visitor;<br>
};<br>
<br>
<br>
int main(int argc, char** argv)<br>
{<br>
    if (argc < 2) {<br>
        llvm::errs() << "Usage: rewritersample <filename> libs\n";<br>
        return 1;<br>
    }<br>
<br>
    clang::DiagnosticOptions diagnosticOptions;<br>
    clang::TextDiagnosticPrinter *pTextDiagnosticPrinter =<br>
        new clang::TextDiagnosticPrinter(<br>
            llvm::outs(),<br>
            &diagnosticOptions);<br>
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;<br>
    clang::DiagnosticsEngine *pDiagnosticsEngine =<br>
        new clang::DiagnosticsEngine(pDiagIDs,<br>
            &diagnosticOptions,<br>
            pTextDiagnosticPrinter);<br>
<br>
    clang::LangOptions languageOptions;<br>
    clang::FileSystemOptions fileSystemOptions;<br>
    clang::FileManager fileManager(fileSystemOptions);<br>
<br>
    clang::SourceManager sourceManager(<br>
        *pDiagnosticsEngine,<br>
        fileManager);<br>
<br>
    llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions><br>
headerSearchOptions(new clang::HeaderSearchOptions());<br>
        headerSearchOptions->ResourceDir = "/opt/llvm_build" "/lib/clang/"<br>
CLANG_VERSION_STRING;<br>
    // <Warning!!> -- Platform Specific Code lives here<br>
    // This depends on A) that you're running linux and<br>
    // B) that you have the same GCC LIBs installed that<br>
    // I do.<br>
    // Search through Clang itself for something like this,<br>
    // go on, you won't find it. The reason why is Clang<br>
    // has its own versions of std* which are installed under<br>
    // /usr/local/lib/clang/<version>/include/<br>
    // See somewhere around Driver.cpp:77 to see Clang adding<br>
    // its version of the headers to its include path.<br>
        for (int i = 2; i < argc; i++) {<br>
</div></div>            headerSearchOptions->AddPath(argv[i],<br>
<div><div class="h5"><br>
clang::frontend::Angled,<br>
                                                                     false,<br>
                                                                     false);<br>
        }<br>
    // </Warning!!> -- End of Platform Specific Code<br>
<br>
    clang::TargetOptions targetOptions;<br>
    targetOptions.Triple = llvm::sys::getDefaultTargetTriple();<br>
<br>
    clang::TargetInfo *pTargetInfo =<br>
        clang::TargetInfo::CreateTargetInfo(<br>
            *pDiagnosticsEngine,<br>
            &targetOptions);<br>
<br>
    clang::HeaderSearch headerSearch(headerSearchOptions,<br>
                                     fileManager,<br>
                                     *pDiagnosticsEngine,<br>
                                     languageOptions,<br>
                                     pTargetInfo);<br>
    clang::CompilerInstance compInst;<br>
<br>
    llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> pOpts( new<br>
clang::PreprocessorOptions());<br>
    clang::Preprocessor preprocessor(<br>
        pOpts,<br>
        *pDiagnosticsEngine,<br>
        languageOptions,<br>
        pTargetInfo,<br>
        sourceManager,<br>
        headerSearch,<br>
        compInst);<br>
<br>
    clang::FrontendOptions frontendOptions;<br>
    clang::InitializePreprocessor(<br>
        preprocessor,<br>
        *pOpts,<br>
        *headerSearchOptions,<br>
        frontendOptions);<br>
<br>
    const clang::FileEntry *pFile = fileManager.getFile(<br>
        argv[1]);<br>
    sourceManager.createMainFileID(pFile);<br>
<br>
    const clang::TargetInfo &targetInfo = *pTargetInfo;<br>
<br>
    clang::IdentifierTable identifierTable(languageOptions);<br>
    clang::SelectorTable selectorTable;<br>
<br>
    clang::Builtin::Context builtinContext;<br>
    builtinContext.InitializeTarget(targetInfo);<br>
    clang::ASTContext astContext(<br>
        languageOptions,<br>
        sourceManager,<br>
        pTargetInfo,<br>
        identifierTable,<br>
        selectorTable,<br>
        builtinContext,<br>
        0 /* size_reserve*/);<br>
   MyASTConsumer astConsumer;<br>
<br>
    clang::Sema sema(<br>
        preprocessor,<br>
        astContext,<br>
        astConsumer);<br>
<br>
    pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor);<br>
    clang::ParseAST(preprocessor, &astConsumer, astContext);<br>
    pTextDiagnosticPrinter->EndSourceFile();<br>
    return 0;<br>
}<br>
<br>
</div></div><div class="im">I run the executable in this way<br>
<br>
./ast_analyzer infile.cpp /usr/include/c++/4.6<br>
/usr/include/c++/4.6/i686-linux-gnu /usr/include/c++/4.6/parallel/<br>
/usr/include/c++/4.6/tr1 /usr/include/i386-linux-gnu/c++/4.6<br>
</div>/usr/include/c++/4.6 /usr/include<br>
/usr/src/linux-headers-3.2.0-35/include/linux<br>
/usr/src/linux-headers-3.2.0-35/include<br>
<br>
where infile.cpp begins with<br>
<br>
#include <iostream><br>
<div class="im"><br>
and I obtain the following error<br>
<br>
</div>In file included from input04.c:1:<br>
In file included from /usr/include/c++/4.6/iostream:40:<br>
In file included from /usr/include/c++/4.6/ostream:40:<br>
In file included from /usr/include/c++/4.6/ios:39:<br>
In file included from /usr/include/c++/4.6/iosfwd:41:<br>
/usr/include/c++/4.6/bits/stringfwd.h:43:1: error: unknown type name<br>
'namespace'<br>
namespace std _GLIBCXX_VISIBILITY(default)<br>
^<br>
/usr/include/c++/4.6/bits/stringfwd.h:43:43: error: expected ';' after top<br>
level    declarator<br>
namespace std _GLIBCXX_VISIBILITY(default)<br>
                                      ^<br>
In file included from input04.c:1:<br>
In file included from /usr/include/c++/4.6/iostream:40:<br>
In file included from /usr/include/c++/4.6/ostream:40:<br>
In file included from /usr/include/c++/4.6/ios:42:<br>
In file included from /usr/include/c++/4.6/bits/localefwd.h:42:<br>
In file included from<br>
/usr/include/c++/4.6/i686-linux-gnu/bits/c++locale.h:42:<br>
In file included from /usr/include/c++/4.6/clocale:44:<br>
/usr/include/locale.h:30:10: fatal error: 'bits/locale.h' file not found<br>
#include <bits/locale.h><br>
<div class="im">         ^<br>
<br>
Could you please help clarifying?<br>
<br>
<br>
<br>
<br>
--<br>
</div>View this message in context: <a href="http://clang-developers.42468.n3.nabble.com/slurping-include-files-tp4031016p4031017.html" target="_blank">http://clang-developers.42468.n3.nabble.com/slurping-include-files-tp4031016p4031017.html</a><br>

<div class="HOEnZb"><div class="h5">Sent from the Clang Developers mailing list archive at Nabble.com.<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div>