diff --git a/src/lib_cxx/data/parser/cxx/CxxParser.cpp b/src/lib_cxx/data/parser/cxx/CxxParser.cpp index 14fbbccb..d3b0b239 100644 --- a/src/lib_cxx/data/parser/cxx/CxxParser.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxParser.cpp @@ -1,6 +1,11 @@ #include "data/parser/cxx/CxxParser.h" +#include +#include +#include +#include #include +#include #include #include "data/indexer/IndexerCommandCxxCdb.h" @@ -19,6 +24,57 @@ namespace { + // copied from clang codebase + clang::driver::Driver *newDriver( + clang::DiagnosticsEngine *Diagnostics, const char *BinaryName, + clang::IntrusiveRefCntPtr VFS) { + clang::driver::Driver *CompilerDriver = + new clang::driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(), + *Diagnostics, std::move(VFS)); + CompilerDriver->setTitle("clang_based_tool"); + return CompilerDriver; + } + + // copied and stitched together from clang codebase + std::string getClangInvocationString(const clang::tooling::CompilationDatabase* compilationDatabase) + { + if (!compilationDatabase->getAllCompileCommands().empty()) + { + std::vector CommandLine = compilationDatabase->getAllCompileCommands().front().CommandLine; + + std::vector Argv; + for (const std::string &Str : CommandLine) + Argv.push_back(Str.c_str()); + const char *const BinaryName = Argv[0]; + clang::IntrusiveRefCntPtr DiagOpts = new clang::DiagnosticOptions(); + unsigned MissingArgIndex, MissingArgCount; + std::unique_ptr Opts = clang::driver::createDriverOptTable(); + llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs( + clang::ArrayRef(Argv).slice(1), MissingArgIndex, MissingArgCount); + clang::ParseDiagnosticArgs(*DiagOpts, ParsedArgs); + clang::DiagnosticsEngine Diagnostics( + clang::IntrusiveRefCntPtr(new clang::DiagnosticIDs()), &*DiagOpts); + + llvm::IntrusiveRefCntPtr Files(new clang::FileManager(clang::FileSystemOptions())); + + const std::unique_ptr Driver( + newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem())); + // Since the input might only be virtual, don't check whether it exists. + Driver->setCheckInputsExist(false); + const std::unique_ptr Compilation( + Driver->BuildCompilation(llvm::makeArrayRef(Argv))); + if (Compilation) + { + std::string s; + llvm::raw_string_ostream ss(s); + Compilation->getJobs().Print(ss, "", true); + ss.flush(); + return utility::trim(s); + } + } + return ""; + } + std::vector prependSyntaxOnlyToolArgs(const std::vector& args) { return utility::concat({ "clang-tool", "-fsyntax-only" }, args); @@ -128,6 +184,8 @@ void CxxParser::runTool(clang::tooling::CompilationDatabase* compilationDatabase tool.setDiagnosticConsumer(diagnostics.get()); + LOG_INFO("Clang Invocation: " + getClangInvocationString(compilationDatabase)); + ASTActionFactory actionFactory(m_client, canonicalFilePathCache); tool.run(&actionFactory); } @@ -139,9 +197,6 @@ std::vector CxxParser::getCommandlineArgumentsEssential( ) const { std::vector args; - // verbose - // args.push_back("-v"); - // The option -fno-delayed-template-parsing signals that templates that there should // be AST elements for unused template functions as well. args.push_back("-fno-delayed-template-parsing");