bool Parse( Furrovine::String filename ) { class ASTDeclConsumer : public clang::ASTConsumer { public: ASTDeclConsumer( std::vector<clang::Decl*>& arg ) : vec( arg ) {} std::vector<clang::Decl*>& vec; bool HandleTopLevelDecl( clang::DeclGroupRef arg ) { for ( auto && x : arg ) { vec.push_back( x ); } return true; } }; ASTDeclConsumer astconsumer( declarations ); llvm::StringRef llvmfilename( reinterpret_cast<char*>( filename.data( ) ) ); clang::CompilerInstance ci; clang::DiagnosticsEngine diagnosticsengine( diagnosticids, llvmdiagnosticsoptions.getPtr(), new clang::TextDiagnosticPrinter( errorstream, llvmdiagnosticsoptions.getPtr(), false ), true ); clang::FileManager filemanager( filesystemoptions ); clang::SourceManager sourcemanager( diagnosticsengine, filemanager ); std::unique_ptr<clang::TargetInfo> targetinfo( clang::TargetInfo::CreateTargetInfo( diagnosticsengine, &targetoptions ) ); targetinfo->setCXXABI( clang::TargetCXXABI::Microsoft ); clang::HeaderSearchOptions& headersearchoptions = *llvmheadersearchoptions; clang::HeaderSearch hs( llvmheadersearchoptions, filemanager, diagnosticsengine, languageoptions, targetinfo.get( ) ); clang::PreprocessorOptions& preprocessoroptions = *llvmpreprocessoroptions; clang::Preprocessor preprocessor( llvmpreprocessoroptions, diagnosticsengine, languageoptions, targetinfo.get( ), sourcemanager, hs, ci ); clang::InitializePreprocessor( preprocessor, preprocessoroptions, headersearchoptions, frontendoptions ); preprocessor.getBuiltinInfo( ).InitializeBuiltins( preprocessor.getIdentifierTable( ), languageoptions ); clang::ASTContext astcontext( languageoptions, sourcemanager, targetinfo.get( ), preprocessor.getIdentifierTable( ), preprocessor.getSelectorTable( ), preprocessor.getBuiltinInfo( ), 1024 ); clang::Sema sema( preprocessor, astcontext, astconsumer, clang::TU_Complete, null ); const clang::DirectoryLookup* directlookup = nullptr; auto entry = hs.LookupFile( llvmfilename, true, nullptr, directlookup, nullptr, nullptr, nullptr, nullptr ); if ( !entry ) entry = filemanager.getFile( llvmfilename ); if ( !entry ) throw Furrovine::TException<std::exception>( "Could not find file " + filename ); auto fileid = sourcemanager.createFileID( entry, clang::SourceLocation( ), clang::SrcMgr::CharacteristicKind::C_User ); if ( fileid.isInvalid( ) ) throw Furrovine::TException<std::exception>( "Error translating file " + filename ); sourcemanager.setMainFileID( fileid ); diagnosticsengine.getClient( )->BeginSourceFile( languageoptions, &preprocessor ); clang::ParseAST( sema ); diagnosticsengine.getClient( )->EndSourceFile( ); return diagnosticsengine.getClient( )->getNumErrors() == 0; }
/// \brief Configure the diagnostics object for use with ASTUnit. void ASTUnit::ConfigureDiags(llvm::IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, const char **ArgBegin, const char **ArgEnd, ASTUnit &AST, bool CaptureDiagnostics) { if (!Diags.getPtr()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. DiagnosticOptions DiagOpts; DiagnosticConsumer *Client = 0; if (CaptureDiagnostics) Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd- ArgBegin, ArgBegin, Client); } else if (CaptureDiagnostics) { Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); } }