title: failing to parse C++ using llvm and clang
body: <p>I'm writing a little tool with llvm to parse C and C++ code, but I can't seem to get it to successfully parse C++ at all. I'm probably missing something obvious.</p>
  
  <p>This is what I have so far:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  #include "llvm/Support/Host.h"
  #include "llvm/Support/MemoryBuffer.h"
  #include "llvm/ADT/IntrusiveRefCntPtr.h"
  #include "llvm/ADT/OwningPtr.h"
  #include "llvm/ADT/StringRef.h"
  #include "llvm/Support/raw_ostream.h"
  
  #include "clang/Basic/DiagnosticOptions.h"
  #include "clang/Frontend/TextDiagnosticPrinter.h"
  #include "clang/Frontend/CompilerInstance.h"
  #include "clang/Frontend/CompilerInvocation.h"
  #include "clang/Frontend/FrontendOptions.h"
  #include "clang/Frontend/LangStandard.h"
  #include "clang/Basic/TargetOptions.h"
  #include "clang/Basic/TargetInfo.h"
  #include "clang/Basic/FileManager.h"
  #include "clang/Basic/SourceManager.h"
  #include "clang/Basic/LangOptions.h"
  #include "clang/Lex/Preprocessor.h"
  #include "clang/Lex/HeaderSearch.h"
  #include "clang/Lex/DirectoryLookup.h"
  #include "clang/Basic/Diagnostic.h"
  #include "clang/AST/RecursiveASTVisitor.h"
  #include "clang/AST/ASTConsumer.h"
  #include "clang/Parse/ParseAST.h"
  
  class MyASTConsumer : public clang::ASTConsumer {
      public:
          bool HandleTopLevelDecl(clang::DeclGroupRef d);
          virtual ~MyASTConsumer() { }
  };
  
  bool MyASTConsumer::HandleTopLevelDecl(clang::DeclGroupRef d)
  {
      for(auto ii = d.begin(); ii != d.end(); ii++)
      {
          printf("decl type: %s\n", (*ii)-&gt;getDeclKindName()); 
          auto namedDecl = llvm::dyn_cast&lt;clang::NamedDecl&gt;(*ii);
          if(namedDecl)
          {
              printf("name: %s\n", namedDecl-&gt;getName().data());
          }
      }
  
      return true;
  }
  
  int main(int, char **argv)
  {
      using clang::CompilerInstance;
      using clang::TargetOptions;
      using clang::TargetInfo;
      using clang::FileEntry;
      using clang::DiagnosticOptions;
      using clang::TextDiagnosticPrinter;
      using clang::SrcMgr::CharacteristicKind;
      using clang::StringRef;
      using clang::DirectoryLookup;
      using llvm::MemoryBuffer;
      using clang::LangOptions;
      using clang::FrontendOptions;
      using clang::LangStandard;
      using clang::CompilerInvocation;
      using clang::InitializePreprocessor;
      using clang::Preprocessor;
      using clang::PreprocessorOptions;
      using clang::HeaderSearch;
      using clang::HeaderSearchOptions;
  
      CompilerInstance ci;
      DiagnosticOptions diagnosticOptions;
      ci.createDiagnostics();
  
      CompilerInvocation *invocation = new CompilerInvocation;
  
      LangOptions &amp;langOpts = ci.getLangOpts();
      langOpts.RTTI = 1;
      langOpts.Bool = 1;
      langOpts.CPlusPlus11 = 1;
      langOpts.GNUKeywords = 1;
      langOpts.CXXExceptions = 1;
      langOpts.POSIXThreads = 1;
      langOpts.SpellChecking = 1;
  
      invocation-&gt;setLangDefaults(langOpts, clang::IK_CXX, LangStandard::lang_gnucxx11);
  
      ci.setInvocation(invocation);
  
      llvm::IntrusiveRefCntPtr&lt;TargetOptions&gt; pto( new TargetOptions() );
      pto-&gt;Triple = llvm::sys::getDefaultTargetTriple();
  
      llvm::IntrusiveRefCntPtr&lt;TargetInfo&gt; pti(TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr()));
      ci.setTarget(pti.getPtr());
  
      ci.createFileManager();
      auto &amp;fileManager = ci.getFileManager();
  
      ci.createSourceManager(fileManager);
  
      llvm::IntrusiveRefCntPtr&lt;HeaderSearchOptions&gt; headerSearchOpts( new HeaderSearchOptions() );
  
      ci.createPreprocessor();
      auto &amp;pp = ci.getPreprocessor();
      pp.setPredefines(builtinMacros);
  
      HeaderSearch &amp;headerSearch = pp.getHeaderSearchInfo();
  
      for(auto &amp;inc: builtinIncludePaths)
      {
          auto dirEntry = fileManager.getDirectory(StringRef(inc), true);
          DirectoryLookup dirLookup(dirEntry, CharacteristicKind::C_System, false);
          headerSearch.AddSearchPath (dirLookup, true);
      }
  
      MyASTConsumer *astConsumer = new MyASTConsumer();
      ci.setASTConsumer(astConsumer);
  
      ci.createASTContext();
  
      const FileEntry *pFile = fileManager.getFile(argv[1]);
      auto &amp;sourceManager = ci.getSourceManager();
  
      sourceManager.createMainFileID(pFile);
      ci.getDiagnosticClient().BeginSourceFile(
          ci.getLangOpts(),
          &amp;pp
      );
  
      clang::ParseAST(pp, astConsumer, ci.getASTContext());
      ci.getDiagnosticClient().EndSourceFile();
  
      return 0;
  }
  </code></pre>
  
  <p>It does parse C just fine, but it errors out on the <code>namespace</code> keyword and <code>extern "C" {</code> blocks. So far I'm stumped. If anyone has a clue, something I'm missing, please share.</p>