| //===--- Compiler.cpp -------------------------------------------*- C++-*-===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===---------------------------------------------------------------------===// | 
 |  | 
 | #include "Compiler.h" | 
 | #include "Logger.h" | 
 | #include "clang/Basic/TargetInfo.h" | 
 | #include "clang/Lex/PreprocessorOptions.h" | 
 | #include "llvm/Support/Format.h" | 
 | #include "llvm/Support/FormatVariadic.h" | 
 |  | 
 | namespace clang { | 
 | namespace clangd { | 
 |  | 
 | void IgnoreDiagnostics::log(DiagnosticsEngine::Level DiagLevel, | 
 |                             const clang::Diagnostic &Info) { | 
 |   SmallString<64> Message; | 
 |   Info.FormatDiagnostic(Message); | 
 |  | 
 |   SmallString<64> Location; | 
 |   if (Info.hasSourceManager() && Info.getLocation().isValid()) { | 
 |     auto &SourceMgr = Info.getSourceManager(); | 
 |     auto Loc = SourceMgr.getFileLoc(Info.getLocation()); | 
 |     llvm::raw_svector_ostream OS(Location); | 
 |     Loc.print(OS, SourceMgr); | 
 |     OS << ":"; | 
 |   } | 
 |  | 
 |   clangd::log("Ignored diagnostic. {0}{1}", Location, Message); | 
 | } | 
 |  | 
 | void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, | 
 |                                          const clang::Diagnostic &Info) { | 
 |   IgnoreDiagnostics::log(DiagLevel, Info); | 
 | } | 
 |  | 
 | std::unique_ptr<CompilerInstance> | 
 | prepareCompilerInstance(std::unique_ptr<clang::CompilerInvocation> CI, | 
 |                         const PrecompiledPreamble *Preamble, | 
 |                         std::unique_ptr<llvm::MemoryBuffer> Buffer, | 
 |                         std::shared_ptr<PCHContainerOperations> PCHs, | 
 |                         IntrusiveRefCntPtr<vfs::FileSystem> VFS, | 
 |                         DiagnosticConsumer &DiagsClient) { | 
 |   assert(VFS && "VFS is null"); | 
 |   assert(!CI->getPreprocessorOpts().RetainRemappedFileBuffers && | 
 |          "Setting RetainRemappedFileBuffers to true will cause a memory leak " | 
 |          "of ContentsBuffer"); | 
 |  | 
 |   // NOTE: we use Buffer.get() when adding remapped files, so we have to make | 
 |   // sure it will be released if no error is emitted. | 
 |   if (Preamble) { | 
 |     Preamble->OverridePreamble(*CI, VFS, Buffer.get()); | 
 |   } else { | 
 |     CI->getPreprocessorOpts().addRemappedFile( | 
 |         CI->getFrontendOpts().Inputs[0].getFile(), Buffer.get()); | 
 |   } | 
 |  | 
 |   auto Clang = llvm::make_unique<CompilerInstance>(PCHs); | 
 |   Clang->setInvocation(std::move(CI)); | 
 |   Clang->createDiagnostics(&DiagsClient, false); | 
 |  | 
 |   if (auto VFSWithRemapping = createVFSFromCompilerInvocation( | 
 |           Clang->getInvocation(), Clang->getDiagnostics(), VFS)) | 
 |     VFS = VFSWithRemapping; | 
 |   Clang->setVirtualFileSystem(VFS); | 
 |  | 
 |   Clang->setTarget(TargetInfo::CreateTargetInfo( | 
 |       Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); | 
 |   if (!Clang->hasTarget()) | 
 |     return nullptr; | 
 |  | 
 |   // RemappedFileBuffers will handle the lifetime of the Buffer pointer, | 
 |   // release it. | 
 |   Buffer.release(); | 
 |   return Clang; | 
 | } | 
 |  | 
 | } // namespace clangd | 
 | } // namespace clang |